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.8 2004/01/08 06:46:43 pierre 00010 Doxygen the file 00011 00012 Revision 1.7 2003/12/03 00:57:20 pierre 00013 ctlM fix 00014 00015 Revision 1.6 2002/09/28 00:49:08 pierre 00016 Add EB_USER_ERROR example 00017 00018 Revision 1.5 2002/09/25 18:38:03 pierre 00019 correct: header passing, user field, abort run 00020 00021 Revision 1.4 2002/07/13 05:46:10 pierre 00022 added ybos comments 00023 00024 Revision 1.3 2002/06/14 04:59:46 pierre 00025 revised for ybos 00026 00027 Revision 1.2 2002/01/17 23:34:29 pierre 00028 doc++ format 00029 00030 Revision 1.1.1.1 2002/01/17 19:49:54 pierre 00031 Initial Version 00032 00033 \********************************************************************/ 00034 /** @file ebuser.c 00035 The Event builder user file 00036 */ 00037 00038 #include <stdio.h> 00039 #include "midas.h" 00040 #include "mevb.h" 00041 #include "ybos.h" 00042 00043 INT eb_begin_of_run(INT, char *, char *); 00044 INT eb_end_of_run(INT, char *); 00045 INT ebuser(INT, EBUILDER_CHANNEL *, EVENT_HEADER *, void *, INT *); 00046 00047 /** 00048 Globals */ 00049 INT lModulo = 100; ///< Global var for testing 00050 00051 /********************************************************************/ 00052 /** 00053 Hook to the event builder task at PreStart transition. 00054 @param rn run number 00055 @param UserField argument from /Ebuilder/Settings 00056 @param error error string to be passed back to the system. 00057 @return EB_SUCCESS 00058 */ 00059 INT eb_begin_of_run(INT rn, char *UserField, char *error) 00060 { 00061 printf("In eb_begin_of_run User_field:%s \n", UserField); 00062 lModulo = atoi(UserField); 00063 return EB_SUCCESS; 00064 } 00065 00066 /********************************************************************/ 00067 /** 00068 Hook to the event builder task at completion of event collection after 00069 receiving the Stop transition. 00070 @param rn run number 00071 @param error error string to be passed back to the system. 00072 @return EB_SUCCESS 00073 */ 00074 INT eb_end_of_run(INT rn, char *error) 00075 { 00076 printf("In eb_end_of_run\n"); 00077 return EB_SUCCESS; 00078 } 00079 00080 /********************************************************************/ 00081 /** 00082 Hook to the event builder task after the reception of 00083 all fragments of the same serial number. The destination 00084 event has already the final EVENT_HEADER setup with 00085 the data size set to 0. It is than possible to 00086 add private data at this point using the proper 00087 bank calls. 00088 00089 The ebch[] array structure points to nfragment channel structure 00090 with the following content: 00091 \code 00092 typedef struct { 00093 char name[32]; // Fragment name (Buffer name). 00094 DWORD serial; // Serial fragment number. 00095 char *pfragment; // Pointer to fragment (EVENT_HEADER *) 00096 ... 00097 } EBUILDER_CHANNEL; 00098 \endcode 00099 00100 The correct code for including your own MIDAS bank is shown below where 00101 \b TID_xxx is one of the valid Bank type starting with \b TID_ for 00102 midas format or \b xxx_BKTYPE for Ybos data format. 00103 \b bank_name is a 4 character descriptor. 00104 \b pdata has to be declared accordingly with the bank type. 00105 Refers to the ebuser.c source code for further description. 00106 00107 <strong> 00108 It is not possible to mix within the same destination event different event format! 00109 </strong> 00110 00111 \code 00112 // Event is empty, fill it with BANK_HEADER 00113 // If you need to add your own bank at this stage 00114 00115 bk_init(pevent); 00116 bk_create(pevent, bank_name, TID_xxxx, &pdata); 00117 *pdata++ = ...; 00118 *dest_size = bk_close(pevent, pdata); 00119 pheader->data_size = *dest_size + sizeof(EVENT_HEADER); 00120 \endcode 00121 00122 For YBOS format, use the following example. 00123 00124 \code 00125 ybk_init(pevent); 00126 ybk_create(pevent, "EBBK", I4_BKTYPE, &pdata); 00127 *pdata++ = 0x12345678; 00128 *pdata++ = 0x87654321; 00129 *dest_size = ybk_close(pevent, pdata); 00130 *dest_size *= 4; 00131 pheader->data_size = *dest_size + sizeof(YBOS_BANK_HEADER); 00132 \endcode 00133 @param nfrag Number of fragment. 00134 @param ebch Structure to all the fragments. 00135 @param pheader Destination pointer to the header. 00136 @param pevent Destination pointer to the bank header. 00137 @param dest_size Destination event size in bytes. 00138 @return EB_SUCCESS 00139 */ 00140 INT eb_user(INT nfrag, EBUILDER_CHANNEL * ebch, EVENT_HEADER * pheader, void *pevent, 00141 INT * dest_size) 00142 { 00143 INT i, dest_serial, frag_size, serial; 00144 DWORD *plrl; 00145 00146 dest_serial = pheader->serial_number; 00147 printf("DSer#:%d ", dest_serial); 00148 00149 // Loop over fragments. 00150 for (i = 0; i < nfrag; i++) { 00151 frag_size = ((EVENT_HEADER *) ebch[i].pfragment)->data_size; 00152 serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; 00153 printf("Frg#:%d Dsz:%d Ser:%d ", i + 1, frag_size, serial); 00154 00155 // For YBOS fragment Access. 00156 plrl = (DWORD *) (((EVENT_HEADER *) ebch[i].pfragment) + 1); 00157 } 00158 00159 if (!((pheader->serial_number + 1) % lModulo)) { 00160 pheader->trigger_mask = (WORD) 0x8000; 00161 return EB_USER_ERROR; 00162 // or TRIGGER_MASK(pevent) = 0x0505; 00163 printf("This event needs a special mask: 0x%x\n", pheader->trigger_mask); 00164 } 00165 printf("\n"); 00166 return EB_SUCCESS; 00167 }