00001 /********************************************************************\ 00002 00003 Name: ebuser.c 00004 Created by: Pierre-Andre Amaudruz 00005 00006 Contents: User section for the Event builder 00007 00008 $Id: ebuser.c 4054 2007-11-12 10:17:04Z ritt@PSI.CH $ 00009 00010 \********************************************************************/ 00011 /** @file ebuser.c 00012 The Event builder user file 00013 */ 00014 00015 #include <stdio.h> 00016 #include "midas.h" 00017 #include "mevb.h" 00018 #include "ybos.h" 00019 00020 /*-- Globals -------------------------------------------------------*/ 00021 00022 /* The frontend name (client name) as seen by other MIDAS clients */ 00023 char *frontend_name = "Ebuilder"; 00024 00025 /* The frontend file name, don't change it */ 00026 char *frontend_file_name = __FILE__; 00027 00028 /* frontend_loop is called periodically if this variable is TRUE */ 00029 BOOL ebuilder_call_loop = FALSE; 00030 00031 /* A frontend status page is displayed with this frequency in ms */ 00032 INT display_period = 3000; 00033 00034 /* maximum event size produced by this frontend */ 00035 INT max_event_size = 10000; 00036 00037 /* maximum event size for fragmented events (EQ_FRAGMENTED) */ 00038 INT max_event_size_frag = 5 * 1024 * 1024; 00039 00040 /* buffer size to hold events */ 00041 INT event_buffer_size = 10 * 10000; 00042 00043 /** 00044 Globals */ 00045 INT lModulo = 100; ///< Global var for testing passed at BOR 00046 00047 /*-- Function declarations -----------------------------------------*/ 00048 INT ebuilder_init(); 00049 INT ebuilder_exit(); 00050 INT eb_begin_of_run(INT, char *, char *); 00051 INT eb_end_of_run(INT, char *); 00052 INT ebuilder_loop(); 00053 INT ebuser(INT, BOOL mismatch, EBUILDER_CHANNEL *, EVENT_HEADER *, void *, INT *); 00054 INT read_scaler_event(char *pevent, INT off); 00055 extern EBUILDER_SETTINGS ebset; 00056 extern BOOL debug; 00057 00058 /*-- Equipment list ------------------------------------------------*/ 00059 EQUIPMENT equipment[] = { 00060 {"EB", /* equipment name */ 00061 {1, 1, /* event ID, trigger mask */ 00062 "SYSTEM", /* event buffer */ 00063 0, /* equipment type */ 00064 0, /* event source */ 00065 "MIDAS", /* format */ 00066 TRUE, /* enabled */ 00067 }, 00068 }, 00069 00070 {""} 00071 }; 00072 00073 #ifdef __cplusplus 00074 } 00075 #endif 00076 /********************************************************************/ 00077 /********************************************************************/ 00078 00079 /********************************************************************/ 00080 INT ebuilder_init() 00081 { 00082 return EB_SUCCESS; 00083 } 00084 00085 /********************************************************************/ 00086 INT ebuilder_exit() 00087 { 00088 return EB_SUCCESS; 00089 } 00090 00091 /********************************************************************/ 00092 INT ebuilder_loop() 00093 { 00094 return EB_SUCCESS; 00095 } 00096 00097 /********************************************************************/ 00098 /** 00099 Hook to the event builder task at PreStart transition. 00100 @param rn run number 00101 @param UserField argument from /Ebuilder/Settings 00102 @param error error string to be passed back to the system. 00103 @return EB_SUCCESS 00104 */ 00105 INT eb_begin_of_run(INT rn, char *UserField, char *error) 00106 { 00107 printf("In eb_begin_of_run for run:%d User_field:%s \n", rn, UserField); 00108 lModulo = atoi(UserField); 00109 return EB_SUCCESS; 00110 } 00111 00112 /********************************************************************/ 00113 /** 00114 Hook to the event builder task at completion of event collection after 00115 receiving the Stop transition. 00116 @param rn run number 00117 @param error error string to be passed back to the system. 00118 @return EB_SUCCESS 00119 */ 00120 INT eb_end_of_run(INT rn, char *error) 00121 { 00122 printf("In eb_end_of_run\n"); 00123 return EB_SUCCESS; 00124 } 00125 00126 /********************************************************************/ 00127 /** 00128 Hook to the event builder task after the reception of 00129 all fragments of the same serial number. The destination 00130 event has already the final EVENT_HEADER setup with 00131 the data size set to 0. It is than possible to 00132 add private data at this point using the proper 00133 bank calls. 00134 00135 The ebch[] array structure points to nfragment channel structure 00136 with the following content: 00137 \code 00138 typedef struct { 00139 char name[32]; // Fragment name (Buffer name). 00140 DWORD serial; // Serial fragment number. 00141 char *pfragment; // Pointer to fragment (EVENT_HEADER *) 00142 ... 00143 } EBUILDER_CHANNEL; 00144 \endcode 00145 00146 The correct code for including your own MIDAS bank is shown below where 00147 \b TID_xxx is one of the valid Bank type starting with \b TID_ for 00148 midas format or \b xxx_BKTYPE for Ybos data format. 00149 \b bank_name is a 4 character descriptor. 00150 \b pdata has to be declared accordingly with the bank type. 00151 Refers to the ebuser.c source code for further description. 00152 00153 <strong> 00154 It is not possible to mix within the same destination event different event format! 00155 </strong> 00156 00157 \code 00158 // Event is empty, fill it with BANK_HEADER 00159 // If you need to add your own bank at this stage 00160 00161 bk_init(pevent); 00162 bk_create(pevent, bank_name, TID_xxxx, &pdata); 00163 *pdata++ = ...; 00164 00165 *dest_size = bk_size(pevent) + sizeof(EVENT_HEADER); 00166 pheader->data_size = bk_size(pevent); 00167 \endcode 00168 00169 For YBOS format, use the following example. 00170 00171 \code 00172 ybk_init(pevent); 00173 ybk_create(pevent, "EBBK", I4_BKTYPE, &pdata); 00174 *pdata++ = 0x12345678; 00175 *pdata++ = 0x87654321; 00176 *dest_size = ybk_close(pevent, pdata); 00177 *dest_size *= 4; 00178 pheader->data_size = *dest_size; 00179 \endcode 00180 @param nfrag Number of fragment. 00181 @param mismatch Midas Serial number mismatch flag. 00182 @param ebch Structure to all the fragments. 00183 @param pheader Destination pointer to the header. 00184 @param pevent Destination pointer to the bank header. 00185 @param dest_size Destination event size in bytes. 00186 @return EB_SUCCESS 00187 */ 00188 INT eb_user(INT nfrag, BOOL mismatch, EBUILDER_CHANNEL * ebch 00189 , EVENT_HEADER * pheader, void *pevent, INT * dest_size) 00190 { 00191 INT i, frag_size, serial; 00192 DWORD *psrcData; 00193 DWORD *pdata; 00194 00195 // 00196 // Do some extra fragment consistency check 00197 if (mismatch){ 00198 printf("Serial number do not match across fragments\n"); 00199 for (i = 0; i < nfrag; i++) { 00200 serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00201 printf("Ser[%i]:%d ", i + 1, serial); 00202 } 00203 printf("\n"); 00204 return EB_USER_ERROR; 00205 } 00206 00207 // 00208 // Include my own bank 00209 bk_init(pevent); 00210 bk_create(pevent, "MYOW", TID_DWORD, &pdata); 00211 for (i = 0; i < nfrag; i++) { 00212 *pdata++ = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00213 *pdata++ = ((EVENT_HEADER *) ebch[i].pfragment)->time_stamp; 00214 } 00215 *dest_size = bk_size(pevent) + sizeof(EVENT_HEADER); 00216 pheader->data_size = bk_size(pevent); 00217 00218 00219 // 00220 // Destination access 00221 // dest_serial = pheader->serial_number; 00222 // printf("DSer#:%d ", dest_serial); 00223 00224 // Stop run if condition requires 00225 // if (dest_serial == 505) return EB_USER_ERROR; 00226 00227 // Skip event if condition requires 00228 // if (dest_serial == 505) return EB_SKIP; 00229 00230 // 00231 // Loop over fragments. 00232 if (debug) { 00233 for (i = 0; i < nfrag; i++) { 00234 if (ebset.preqfrag[i]) { // printf if channel enable 00235 frag_size = ((EVENT_HEADER *) ebch[i].pfragment)->data_size; 00236 serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00237 printf("Frg#:%d Dsz:%d Ser:%d ", i + 1, frag_size, serial); 00238 // For Data fragment Access. 00239 psrcData = (DWORD *) (((EVENT_HEADER *) ebch[i].pfragment) + 1); 00240 } 00241 } 00242 printf("\n"); 00243 } 00244 return EB_SUCCESS; 00245 }