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 3197 2006-07-31 19:01:21Z ritt $ 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, 0, /* 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 *dest_size = bk_close(pevent, pdata); 00165 pheader->data_size = *dest_size + sizeof(EVENT_HEADER); 00166 \endcode 00167 00168 For YBOS format, use the following example. 00169 00170 \code 00171 ybk_init(pevent); 00172 ybk_create(pevent, "EBBK", I4_BKTYPE, &pdata); 00173 *pdata++ = 0x12345678; 00174 *pdata++ = 0x87654321; 00175 *dest_size = ybk_close(pevent, pdata); 00176 *dest_size *= 4; 00177 pheader->data_size = *dest_size + sizeof(YBOS_BANK_HEADER); 00178 \endcode 00179 @param nfrag Number of fragment. 00180 @param mismatch Midas Serial number mismatch flag. 00181 @param ebch Structure to all the fragments. 00182 @param pheader Destination pointer to the header. 00183 @param pevent Destination pointer to the bank header. 00184 @param dest_size Destination event size in bytes. 00185 @return EB_SUCCESS 00186 */ 00187 INT eb_user(INT nfrag, BOOL mismatch, EBUILDER_CHANNEL * ebch 00188 , EVENT_HEADER * pheader, void *pevent, INT * dest_size) 00189 { 00190 INT i, frag_size, serial; 00191 DWORD *psrcData; 00192 DWORD *pdata; 00193 00194 // 00195 // Do some extra fragment consistency check 00196 if (mismatch){ 00197 printf("Serial number do not match across fragments\n"); 00198 for (i = 0; i < nfrag; i++) { 00199 serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00200 printf("Ser[%i]:%d ", i + 1, serial); 00201 } 00202 printf("\n"); 00203 return EB_USER_ERROR; 00204 } 00205 00206 // 00207 // Include my own bank 00208 bk_init(pevent); 00209 bk_create(pevent, "MYOW", TID_DWORD, &pdata); 00210 for (i = 0; i < nfrag; i++) { 00211 *pdata++ = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00212 *pdata++ = ((EVENT_HEADER *) ebch[i].pfragment)->time_stamp; 00213 } 00214 *dest_size = bk_close(pevent, pdata); 00215 pheader->data_size = *dest_size + sizeof(EVENT_HEADER); 00216 00217 00218 // 00219 // Destination access 00220 // dest_serial = pheader->serial_number; 00221 // printf("DSer#:%d ", dest_serial); 00222 00223 // Stop run if condition requires 00224 // if (dest_serial == 505) return EB_USER_ERROR; 00225 00226 // Skip event if condition requires 00227 // if (dest_serial == 505) return EB_SKIP; 00228 00229 // 00230 // Loop over fragments. 00231 if (debug) { 00232 for (i = 0; i < nfrag; i++) { 00233 if (ebset.preqfrag[i]) { // printf if channel enable 00234 frag_size = ((EVENT_HEADER *) ebch[i].pfragment)->data_size; 00235 serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00236 printf("Frg#:%d Dsz:%d Ser:%d ", i + 1, frag_size, serial); 00237 // For Data fragment Access. 00238 psrcData = (DWORD *) (((EVENT_HEADER *) ebch[i].pfragment) + 1); 00239 } 00240 } 00241 printf("\n"); 00242 } 00243 return EB_SUCCESS; 00244 }