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