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