Always delete TObjArrays created by TString::Tokenize (Ruben)
[u/mrichter/AliRoot.git] / RAW / dateStream.cxx
1 /*
2                              dateStream.c
3                              ============
4
5    Utility to simulate a DATE raw data stream using a given set of raw
6    data files and a configuration file.
7
8    Revision history:
9
10    V01.00  4/05/2004  RD  Created
11    V01.01 25/10/2005  RD  Support added for timestamp
12    V01.02  4/04/2006  RD  Support for CDH
13    V01.03 24/05/2006  RD  Added "Direct disk access" option
14 */
15 #define VID "1.03"
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <assert.h>
21 #include <ctype.h>
22 #include <time.h>
23 #include <cassert>
24 #include "event.h"
25
26 #define DESCRIPTION "DATE raw data stream simulator"
27 #ifdef AIX
28 static
29 #endif
30 char fileHandlerIdent[]= "@(#)""" __FILE__ """: """ DESCRIPTION \
31                          """ """ VID """ """ \
32                          """ compiled """ __DATE__ """ """ __TIME__;
33
34 #define DBG_BASE     if ( debug > 0 )
35 #define DBG_DETAILED if ( debug > 1 )
36 #define DBG_VERBOSE  if ( debug > 2 )
37
38 #ifndef TRUE
39 # define TRUE (0 == 0)
40 #endif
41 #ifndef FALSE
42 # define FALSE (0 == 1)
43 #endif
44
45 const char *myName;
46 int debug;
47 FILE *outF;
48 typedef enum { unknown, ldc, gdc } workingAsType;
49 typedef enum { collider, fixedTarget } workingModeType;
50 workingAsType workingAs;
51 workingModeType workingMode;
52 struct ldcDescriptorStruct {
53   eventLdcIdType id;
54   struct ldcDescriptorStruct *next;
55 } *ldcsHead, *ldcsTail;
56 void *eventsHead, *eventsTail;
57 struct gdcEventDescriptorStruct {
58   struct ldcEventDescriptorStruct *head;
59   struct ldcEventDescriptorStruct *tail;
60   struct gdcEventDescriptorStruct *next;
61   struct eventHeaderStruct header;
62   int loaded;
63   unsigned long32 detPattern;
64   eventTimestampType timestamp; 
65 } *currGdc;
66 struct ldcEventDescriptorStruct {
67   struct equipmentEventDescriptorStruct *head;
68   struct equipmentEventDescriptorStruct *tail;
69   struct ldcEventDescriptorStruct *next;
70   eventLdcIdType id;
71   struct eventHeaderStruct header;
72   int loaded;
73   unsigned long32 detPattern;
74   eventTimestampType timestamp; 
75 } *currLdc;
76 struct equipmentEventDescriptorStruct {
77   struct equipmentEventDescriptorStruct *next;
78   equipmentIdType id;
79   struct payloadDescriptorStruct *payload;
80   struct equipmentHeaderStruct header;
81 } *currEvent;
82 struct payloadDescriptorStruct {
83   struct payloadDescriptorStruct *next;
84   char *fileName;
85   int fileSize;
86   int size;
87   void *data;
88 } *payloadsHead, *payloadsTail;
89 int lineNmb;
90 eventGdcIdType currGdcId;
91 unsigned long32 currDetPattern;
92 eventTimestampType currTimestamp; 
93 eventLdcIdType currLdcId;
94 equipmentIdType currEquipmentId;
95 int currRunNb;
96 int numOfLdcs;
97 int numOfEvents;
98 int createSorEor;
99 int handleCDH;
100 eventIdType oneEventDelta;
101 eventIdType currEventId;
102 int gotAliceTrigger;
103 int bufferData;
104
105 struct commonDataHeaderStruct *cdhRef = NULL;
106
107 void dumpPayload( const struct payloadDescriptorStruct *p ) {
108   char *c;
109   int i;
110   int printable;
111           
112   if ( p->data != NULL ) {
113     for ( i = 0, c = (char *)p->data, printable = TRUE;
114           printable && i != p->size;
115           c++, i++ )
116       printable = isascii( *c );
117     if ( printable ) {
118       printf( "       \"" );
119       for ( i = 0, c = (char *)p->data; i != p->size; c++, i++ ) {
120         if ( *c == '\n' )
121           printf( "\"\n       \"" );
122         else
123           putchar( *c );
124       }
125       if ( *c != '\n' ) printf( "\"\n" );
126     } else {
127       long32 *v;
128       for ( i = 0, v = (long32 *)p->data;
129             i+4 <= p->size;
130             v++, i += 4 ) {
131         if ( i % (4*8) == 0 ) {
132           if ( i != 0 ) printf( "\n" );
133           printf( "       " );
134         }
135         printf( "%08x ", *v );
136       }
137       if ( i < p->size ) {
138         int j = 0;
139
140         printf( "\n       " );
141         while ( i != p->size ) {
142           printf( "%02x ", *((char *)p->data + p->size - j - 1) & 0xff );
143           j++;
144           i++;
145         }
146       }
147     }
148     printf( "\n" );
149   }
150 } /* End of dumpPayload */
151
152 void dumpEvents() {
153   assert( workingAs == ldc || workingAs == gdc );
154   if ( eventsHead != NULL ) {
155     printf( "Events:\n" );
156     if ( workingAs == gdc ) {
157       struct gdcEventDescriptorStruct *gdc;
158
159       for ( gdc = (struct gdcEventDescriptorStruct *)eventsHead;
160             gdc != NULL;
161             gdc = gdc->next ) {
162         struct ldcEventDescriptorStruct *ldc;
163
164         printf( " GDC (%p)\n", (void*)gdc );
165         for ( ldc = gdc->head; ldc != NULL; ldc = ldc->next ) {
166           struct equipmentEventDescriptorStruct *eq;
167             
168           printf( "   LDC (%p): %d\n", (void*)ldc, ldc->id );
169           for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
170             printf( "     EQUIPMENT (%p): %d PAYLOAD (%p):",
171                     (void*)eq,
172                     eq->id,
173                     (void*)eq->payload );
174             fflush( stdout );
175             printf( "\"%s\" (%d bytes)\n",
176                     eq->payload->fileName,
177                     eq->payload->size );
178             dumpPayload( eq->payload );
179           }
180         }
181       }
182     }
183     if ( workingAs == ldc ) {
184       struct ldcEventDescriptorStruct *ldc;
185
186       for ( ldc = (struct ldcEventDescriptorStruct *)eventsHead;
187             ldc != NULL;
188             ldc = ldc->next ) {
189         struct equipmentEventDescriptorStruct *eq;
190             
191         printf( "   LDC\n" );
192         for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
193           printf( "     EQUIPMENT (%p): %d PAYLOAD (%p):",
194                   (void*)eq,
195                   eq->id,
196                   (void*)eq->payload );
197           fflush( stdout );
198           printf( "\"%s\" (%d bytes)\n",
199                   eq->payload->fileName,
200                   eq->payload->size );
201           dumpPayload( eq->payload );
202         }
203       }
204     }
205   } else {
206     printf( "Events: EMPTY\n" );
207   }
208 } /* End of dumpEvents */
209
210 void getLine( char *line, const int maxSize ) {
211   int read;
212   int c;
213
214   for ( read = 0; !feof( stdin ) && !ferror( stdin ) && read != maxSize; read++ ) {
215     if ( (line[read] = getchar()) == '\n' ) break;
216   }
217   if ( ferror( stdin ) ) {
218     fprintf( stderr,
219              "%s: failed to read configuration input errno:%d ",
220              myName, errno );
221     perror( "" );
222     exit( 1 );
223   }
224   if ( feof( stdin ) ) read--;
225   if ( read == maxSize && line[read] != '\n' ) {
226     fprintf( stderr,
227              "%s: Input line # %d too long (%d chars max)\n",
228              myName, lineNmb, maxSize-1 );
229     exit( 1 );
230   }
231   line[ read ] = 0;
232   DBG_VERBOSE {
233     if ( !( read == 0 && feof( stdin ) ) ) {
234       printf( "%d) [%3d] \"%s\"", lineNmb, read, line );
235     }
236   }
237   for ( c = 0; c != read; c++ ) {
238     if ( line[c] == '#' ) {
239       line[c] = 0;
240       break;
241     }
242   }
243   DBG_VERBOSE {
244     if ( read != c ) {
245       printf( " => \"%s\"", line );
246     }
247     if ( feof( stdin ) ) printf( "<<< EOF >>>" );
248     if ( ferror( stdin ) ) printf( "<<< FERROR >>>" );
249     printf( "\n" );
250   }
251 } /* End of getLine */
252
253 void handleLdc( eventLdcIdType ldcId ) {
254   struct ldcDescriptorStruct *ldc;
255
256   if ( ldcsHead != NULL ) {
257     for ( ldc = ldcsHead; ldc != NULL; ldc = ldc->next ) {
258       if ( ldc->id == ldcId ) {
259         return;
260       }
261     }
262   }
263   if ( (ldc = (struct ldcDescriptorStruct *)malloc( sizeof( *ldc ) )) == NULL ) {
264     fprintf( stderr,
265              "%s: Failed to malloc for %d bytes (struct ldcDescriptorStruct)\n",
266              myName, (int)sizeof( *ldc ) );
267     exit( 1 );
268   }
269   ldc->id = ldcId;
270   ldc->next = NULL;
271   if ( ldcsHead == NULL ) {
272     ldcsHead = ldcsTail = ldc;
273   } else {
274     ldcsTail->next = ldc;
275     ldcsTail = ldc;
276   }
277   numOfLdcs++;
278 } /* End of handleLdc */
279
280 void createNewEvent() {
281   assert( workingAs == ldc || workingAs == gdc );
282   if ( workingAs == ldc ) {
283     struct ldcEventDescriptorStruct *p;
284
285     if ( (p = (struct ldcEventDescriptorStruct *)malloc( sizeof( *p ) ))
286            == NULL ) {
287       fprintf( stderr,
288                "%s: failed to malloc for %d bytes (createNewEvent: struct ldcEventDescriptorStruct)",
289                myName, (int)sizeof( *p ) );
290       perror( "" );
291       exit( 1 );
292     }
293     p->loaded = FALSE;
294     p->head = p->tail = NULL;
295     p->next = NULL;
296     currLdc = p;
297     if ( eventsHead == NULL ) {
298       eventsHead = eventsTail = p;
299     } else {
300       struct ldcEventDescriptorStruct *q =
301         (struct ldcEventDescriptorStruct *)eventsTail;
302
303       q->next = p;
304       eventsTail = p;
305     }
306     p->id = currLdcId;
307     p->detPattern = currDetPattern;
308     p->timestamp = currTimestamp;
309   } else if ( workingAs == gdc ) {
310     struct gdcEventDescriptorStruct *p;
311
312     if ( (p = (struct gdcEventDescriptorStruct *)malloc( sizeof( *p ) ))
313            == NULL ) {
314       fprintf( stderr,
315                "%s: failed to malloc for %d bytes (createNewEvent: struct gdcEventDescriptorStruct)",
316                myName, (int)sizeof( *p ) );
317       perror( "" );
318       exit( 1 );
319     }
320     p->loaded = FALSE;
321     p->next = NULL;
322     p->head = p->tail = NULL;
323     currGdc = p;
324     if ( eventsHead == NULL ) {
325       eventsHead = eventsTail = p;
326     } else {
327       struct gdcEventDescriptorStruct *q =
328         (struct gdcEventDescriptorStruct *)eventsTail;
329
330       q->next = p;
331       eventsTail = p;
332     }
333     p->detPattern = currDetPattern;
334     p->timestamp = currTimestamp;
335   }
336 } /* End of createNewEvent */
337
338 void createNewLdcEvent() {
339   struct gdcEventDescriptorStruct *gdcDesc;
340   struct ldcEventDescriptorStruct *p;
341
342   if ( (p = (struct ldcEventDescriptorStruct *)malloc( sizeof( *p ) ))
343          == NULL ) {
344     fprintf( stderr,
345              "%s: failed to malloc for %d bytes (createNewLdcEvent: struct ldcEventDescriptorStruct)",
346              myName, (int)sizeof( *p ) );
347     perror( "" );
348     exit( 1 );
349   }
350   p->id = currLdcId;
351   p->detPattern = currDetPattern;
352   p->timestamp = currTimestamp;
353   p->head = p->tail = NULL;
354   p->next = NULL;
355   gdcDesc = (struct gdcEventDescriptorStruct *)eventsTail;
356   if ( gdcDesc->head == NULL ) {
357     gdcDesc->head = gdcDesc->tail = p;
358   } else {
359     gdcDesc->tail->next = p;
360     gdcDesc->tail = p;
361   }
362   currLdc = p;
363 } /* End of createNewLdcEvent */
364
365 void loadBuffer( struct payloadDescriptorStruct * const payload ) {
366   FILE *f;
367   int bytesRead;
368
369   if ( (f = fopen( payload->fileName, "r" )) == NULL ) {
370     fprintf( stderr,
371              "%s: line:%d payload file \"%s\" not found or not readable, errno:%d. ",
372              myName,
373              lineNmb,
374              payload->fileName,
375              errno );
376     perror( "System-dependent error " );
377     exit( 1 );
378   }
379   if ( (payload->data = malloc( payload->size )) == NULL ) {
380     fprintf( stderr,
381              "%s: line:%d Failed to malloc for payload file \"%s\" size:%d errno:%d ",
382              myName,
383              lineNmb,
384              payload->fileName,
385              payload->size,
386              errno );
387     perror( "System-dependent status " );
388     exit( 1 );
389   }
390   if ( (bytesRead = fread( payload->data, payload->fileSize, 1, f )) != 1 ) {
391     fprintf( stderr,
392              "%s: line:%d Failed to read payload file \"%s\" size:%d requested:1 got:%d feof:%s ferror:%s errno:%d ",
393              myName,
394              lineNmb,
395              payload->fileName,
396              payload->size,
397              bytesRead,
398              feof(f) ? "TRUE" : "false",
399              ferror(f) ? "TRUE" : "false",
400              errno );
401     perror( "System-dependent status " );
402     exit( 1 );
403   }
404   fclose(f);
405   if ( payload->size != payload->fileSize ) {
406     memset( (char *)payload->data + payload->fileSize,
407             0,
408             payload->size - payload->fileSize );
409   }
410 } /* End of loadBuffer */
411
412 void unloadBuffer( struct payloadDescriptorStruct * const payload ) {
413   if ( payload->data != NULL ) {
414     free( payload->data );
415     payload->data = NULL;
416   }
417 } /* End of unloadBuffer */
418
419 void unloadAllBuffers() {
420   struct payloadDescriptorStruct *payload;
421
422   for ( payload = payloadsHead; payload != NULL; payload = payload->next ) {
423     unloadBuffer( payload );
424   }
425 } /* End of unloadAllBuffers */
426
427 void loadPayload( const char *fileName ) {
428   struct payloadDescriptorStruct *payload;
429
430   for ( payload = payloadsHead; payload != NULL; payload = payload->next ) {
431     if ( strcmp( fileName, payload->fileName ) == 0 )
432       break;
433   }
434   if ( payload == NULL ) {
435     FILE *f;
436
437     if ( (payload = (struct payloadDescriptorStruct *)malloc( sizeof( *payload ) ))
438            == NULL ) {
439       fprintf( stderr,
440                "%s: failed to malloc for %d bytes (loadPayload/payloadDescriptorStruct)\n",
441                myName,
442                (int)sizeof( *payload ) );
443       exit( 1 );
444     }
445     if ( (payload->fileName = strdup( fileName )) == NULL ) {
446       fprintf( stderr,
447                "%s: failed to duplicate string \"%s\" (loadPaload/fileName)\n",
448                myName,
449                fileName );
450       exit( 1 );
451     }
452     if ( (f = fopen( fileName, "r" )) == NULL ) {
453       fprintf( stderr,
454                "%s: line:%d payload file \"%s\" not found or not readable, errno:%d. ",
455                myName,
456                lineNmb,
457                fileName,
458                errno );
459       perror( "System-dependent error " );
460       exit( 1 );
461     }
462     if ( fseek( f, 0L, SEEK_END ) != 0 ) {
463       fprintf( stderr,
464                "%s: line:%d Failed to seek payload file \"%s\" errno:%d ",
465                myName,
466                lineNmb,
467                fileName,
468                errno );
469       perror( "System-dependent error " );
470       exit( 1 );
471     }
472     if ( (payload->size = ftell( f )) <= 0 ) {
473       fprintf( stderr,
474                "%s: line:%d Failed to get file \"%s\" size size:%d errno:%d ",
475                myName,
476                lineNmb,
477                fileName,
478                payload->size,
479                errno );
480       perror( "System-dependent status " );
481       exit( 1 );
482     }
483     payload->fileSize = payload->size;
484     while ( (payload->size & 3) != 0 ) payload->size++;
485     fclose( f );
486
487     if ( bufferData ) {
488       loadBuffer( payload );
489     } else {
490       payload->data = NULL;
491     }
492
493     payload->next = NULL;
494     if ( payloadsHead == NULL ) {
495       payloadsHead = payloadsTail = payload;
496     } else {
497       payloadsTail->next = payload;
498       payloadsTail = payload;
499     }
500     DBG_VERBOSE {
501       int b, n;
502
503       printf( "%d)       Payload \"%s\" loaded at %p\n",
504               lineNmb,
505               fileName,
506               (void*)payload );
507       if ( bufferData ) {
508         if ( handleCDH &&
509              strncmp(fileName,"TRG_",4) != 0 ) {
510           struct commonDataHeaderStruct *cdh =
511             (struct commonDataHeaderStruct *)payload->data;
512
513           printf( " CDH: blockLenght:%d=0x%08x ",
514                   cdh->cdhBlockLength, cdh->cdhBlockLength );
515           if ( cdh->cdhBlockLength < sizeof( *cdh ) ) {
516             printf( "TOO SMALL (minimum:%ld=0x%08lx)\n",
517                    (unsigned long)sizeof( *cdh ),
518                    (unsigned long)sizeof( *cdh ) );
519           } else {
520             printf( "version:%d=0x%x ", cdh->cdhVersion, cdh->cdhVersion );
521             if ( cdh->cdhVersion != CDH_VERSION ) {
522               printf( "EXPECTED:%d=%x (decoding may be inaccurate) ",
523                       CDH_VERSION, CDH_VERSION );
524             }
525           }
526           printf( "L1TriggerMessage:0x%x", cdh->cdhL1TriggerMessage );
527           if (  cdh->cdhL1TriggerMessage != 0 ) {
528             for ( b = 0, n = 0; b != 10; b++ ) {
529               if ( (cdh->cdhL1TriggerMessage & (1<<b)) != 0 ) {
530                 if ( n++ != 0 )printf( "+" );
531                 switch (b) {
532                 case 0: printf( "L1SwC" ); break;
533                 case 1: printf( "ESR" ); break;
534                 case 2: printf( "RoC1" ); break;
535                 case 3: printf( "RoC2" ); break;
536                 case 4: printf( "RoC3" ); break;
537                 case 5: printf( "RoC4" ); break;
538                 case 6: printf( "ClT" ); break;
539                 default: printf( "spare %d", b+14 );
540                 }
541               }
542             }
543             printf( ">" );
544           }
545           printf( " " );
546           if ( cdh->cdhMBZ0 != 0 )
547             printf( "MBZ0:0x%x ",
548                     cdh->cdhMBZ0 );
549           printf( "\n" );
550           
551           printf( "      " );
552           printf( "EventId2(orbit):%d=0x%x ",
553                   cdh->cdhEventId2, cdh->cdhEventId2 );
554           printf( "EventId1(bunchCrossing):%d=0x%x ",
555                   cdh->cdhEventId1, cdh->cdhEventId1 );
556           printf( "\n" );
557           
558           printf( "      " );
559           if ( cdh->cdhMBZ1 != 0 )
560             printf( "MBZ1:0x%x ",
561                     cdh->cdhMBZ1 );
562           printf( "BlockAttributes:0x%x",
563                   cdh->cdhBlockAttributes );
564           if ( cdh->cdhBlockAttributes != 0 ) {
565             printf( "=<" );
566             for ( b = 0, n = 0; b != 8; b++ ) {
567               if ( (cdh->cdhBlockAttributes & (1<<b)) != 0 ) {
568                 if ( n++ != 0 )
569                   printf( "+" );
570                 printf( "%d", b );
571               }
572             }
573             printf( ">" );
574           }
575           printf( " " );
576           printf( "ParticipatingSubDetectors:0x%x ",
577                   cdh->cdhParticipatingSubDetectors );
578           printf( "\n" );
579           printf( "      " );
580           
581           if ( cdh->cdhMBZ2 != 0 )
582             printf( "MBZ2:0x%x ",
583                     cdh->cdhMBZ2 );
584           printf( "Status/Error:0x%x", cdh->cdhStatusErrorBits );
585           if ( cdh->cdhStatusErrorBits != 0 ) {
586             printf( "=<" );
587             for ( b = 0,n = 0; b != 16; b++ ) {
588               if ( (cdh->cdhStatusErrorBits & (1<<b)) != 0 ) {
589                 if ( n++ != 0 ) printf( "+" );
590                 switch (b) {
591                 case 0: printf( "TriggerOverLapError" ); break;
592                 case 1: printf( "TriggerMissingError" ); break;
593                 case 2: printf( "DataParityError" ); break;
594                 case 3: printf( "ControlParityError" ); break;
595                 case 4: printf( "TriggerInformationUnavailable" ); break;
596                 case 5: printf( "FEEError" ); break;
597                 case 6: printf( "HLTDecision" ); break;
598                 case 7: printf( "HLTPayload" ); break;
599                 case 8: printf( "DDGPayload" ); break;
600                 default: printf( "spare %d", b );
601                 }
602               }
603             }
604             printf( ">" );
605           }
606           printf( " " );
607           printf( "MiniEventId(bunchCrossing):%d=0x%x ",
608                   cdh->cdhMiniEventId, cdh->cdhMiniEventId );
609           printf( "\n" );
610           
611           printf( "      " );
612           printf( "Trigger classes: 0x(%05x-%08x)",
613                   cdh->cdhTriggerClassesHigh,
614                   cdh->cdhTriggerClassesLow );
615           if ( cdh->cdhTriggerClassesHigh != 0
616                || cdh->cdhTriggerClassesLow != 0 ) {
617             printf( "=<" );
618             for ( b=0, n=0; b != 32; b++ ) {
619               if ( (cdh->cdhTriggerClassesLow & (1<<b)) != 0 ) {
620                 if ( n++ != 0 ) printf( "+" );
621                 printf( "%d", b );
622               }
623             }
624             for ( b=0; b != 18; b++ ) {
625               if ( (cdh->cdhTriggerClassesHigh & (1<<b)) != 0 ) {
626                 if ( n++ != 0 ) printf( "+" );
627                 printf( "%d", b+32 );
628               }
629             }
630             printf( ">" );
631           }
632           printf( "\n" );
633           
634           printf( "      " );
635           if ( cdh->cdhMBZ3 != 0 ) {
636             printf( "MBZ3:0x%x ",
637                     cdh->cdhMBZ3 );
638           }
639           printf( "ROI:0x(%08x-%01x)", cdh->cdhRoiHigh, cdh->cdhRoiLow );
640           if ( cdh->cdhRoiHigh != 0
641                || cdh->cdhRoiLow != 0 ) {
642             printf( "=<" );
643             for ( b=0, n=0; b != 5; b++ ) {
644               if ( (cdh->cdhRoiLow & (1<<b)) != 0 ) {
645                 if ( n++ != 0 ) printf( "+" );
646                 printf( "%d", b );
647               }
648             }
649             for ( b=0; b != 32; b++ ) {
650               if ( (cdh->cdhRoiHigh & (1<<b)) != 0 ) {
651                 if ( n++ != 0 ) printf( "+" );
652                 printf( "%d", b+4 );
653               }
654             }
655             printf( ">" );
656           }
657           printf( "\n" );
658         }
659       }
660     }
661   } else {
662     DBG_VERBOSE
663       printf( "%d)       Payload \"%s\" already loaded at %p\n",
664               lineNmb,
665               fileName,
666               (void*)payload );
667   }
668
669   currEvent->payload = payload;
670 } /* End of loadPayload */
671
672 void parseEquipment( char * const line ) {
673   struct equipmentEventDescriptorStruct *equipment;
674   int payloadFound = FALSE;
675   char *p;
676   char *keyword;
677
678   if ( (equipment =
679          (struct equipmentEventDescriptorStruct *)malloc( sizeof( *equipment ) )) == NULL ) {
680     fprintf( stderr,
681              "%s: filed to malloc for %d bytes (parseEquipment/equipmentEventDescriptorStruct) errno:%d ",
682              myName,
683              (int)sizeof( *equipment ),
684              errno );
685     perror( "" );
686     exit( 1 );
687   }
688   currEvent = equipment;
689
690   p = line;
691   while ( (keyword = strtok_r( p, " \t", &p )) != NULL ) {
692     DBG_VERBOSE printf( "%d)     Equipment - Keyword:\"%s\"\n",
693                         lineNmb,
694                         keyword );
695     if ( strcasecmp( "id", keyword ) == 0 ) {
696       char *idNum;
697
698       if ( (idNum = strtok_r( p, " \t", &p )) == NULL ) {
699         fprintf( stderr,
700                  "%s: line:%d EQUIPMENT declaration, ID needed",
701                  myName,
702                  lineNmb );
703         exit( 1 );
704       }
705       if ( sscanf( idNum, "%d", &currEquipmentId ) != 1 ) {
706         fprintf( stderr,
707                  "%s: line:%d EQUIPMENT declaration, numeric ID needed (%s)",
708                  myName,
709                  lineNmb,
710                  idNum );
711         exit( 1 );
712       }
713       DBG_VERBOSE printf( "%d)     EQUIPMENT - ID:%d\n",
714                           lineNmb,
715                           currEquipmentId );
716     } else if ( strncasecmp( "pay", keyword, 3 ) == 0 ) {
717       char *fileName;
718
719       if ( (fileName = strtok_r( p, " \t", &p )) == NULL ) {
720         fprintf( stderr,
721                  "%s line:%d Payload without filename found\n",
722                  myName,
723                  lineNmb );
724         exit( 1 );
725       }
726       DBG_VERBOSE printf( "%d)     Equipment - Payload:\"%s\"\n",
727                           lineNmb,
728                           fileName );
729       if ( payloadFound ) {
730         fprintf( stderr,
731                  "%s line:%d Payload with multiple filenames found\n",
732                  myName,
733                  lineNmb );
734         exit( 1 );
735       }
736       loadPayload( fileName );
737       payloadFound = TRUE;
738     } else {
739       fprintf( stderr,
740                "%s: line:%d Equipment declaration, unknown keyword \"%s\"\n",
741                myName,
742                lineNmb,
743                keyword );
744       exit( 1 );
745     }
746   }
747   if ( !payloadFound ) {
748     fprintf( stderr,
749              "%s: line:%d Equipment without payload found\n",
750              myName,
751              lineNmb );
752     exit( 1 );
753   }
754
755   equipment->id = currEquipmentId;
756   equipment->next = NULL;
757   if ( currLdc->head == NULL ) {
758     currLdc->head = currLdc->tail = equipment;
759   } else {
760     currLdc->tail->next = equipment;
761     currLdc->tail = equipment;
762   }
763 } /* End of parseEquipment */
764
765 void parseGdc( char * const line ) {
766   char *p;
767   char *keyword;
768
769   p = line;
770   while ( (keyword = strtok_r( p, " \t", &p )) != NULL ) {
771     if ( strcasecmp( "id", keyword ) == 0 ) {
772       char *idNum;
773
774       if ( (idNum = strtok_r( p, " \t", &p )) == NULL ) {
775         fprintf( stderr,
776                  "%s: line:%d GDC declaration, ID needed",
777                  myName,
778                  lineNmb );
779         exit( 1 );
780       }
781       int inCurrGdcId;
782       if ( sscanf( idNum, "%d", &inCurrGdcId ) != 1 ) {
783         fprintf( stderr,
784                  "%s: line:%d GDC declaration, numeric ID needed (%s)",
785                  myName,
786                  lineNmb,
787                  idNum );
788         exit( 1 );
789       }
790       currGdcId = (eventGdcIdType)inCurrGdcId;
791       DBG_VERBOSE printf( "%d)     GDC - ID:%d\n",
792                           lineNmb,
793                           currGdcId );
794     } else if ( strcasecmp( "DetectorPattern", keyword ) == 0 ) {
795       char *detPattern;
796
797       if ( (detPattern = strtok_r( p, " \t", &p )) == NULL ) {
798         fprintf( stderr,
799                  "%s: line:%d GDC declaration, DetectorPattern needed",
800                  myName,
801                  lineNmb );
802         exit( 1 );
803       }
804       if ( sscanf( detPattern, "%u", &currDetPattern ) != 1 ) {
805         fprintf( stderr,
806                  "%s: line:%d GDC declaration, numeric DetectorPattern needed (%s)",
807                  myName,
808                  lineNmb,
809                  detPattern );
810         exit( 1 );
811       }
812       DBG_VERBOSE printf( "%d)     GDC - DetectorPattern:%u\n",
813                           lineNmb,
814                           currDetPattern );
815     } else if ( strcasecmp( "Timestamp", keyword ) == 0 ) {
816       char *timestamp;
817
818       if ( (timestamp = strtok_r( p, " \t", &p )) == NULL ) {
819         fprintf( stderr,
820                  "%s: line:%d GDC declaration, Timestamp needed",
821                  myName,
822                  lineNmb );
823         exit( 1 );
824       }
825       if ( sscanf( timestamp, "%u", &currTimestamp ) != 1 ) {
826         fprintf( stderr,
827                  "%s: line:%d GDC declaration, numeric Timestamp needed (%s)",
828                  myName,
829                  lineNmb,
830                  timestamp );
831         exit( 1 );
832       }
833       DBG_VERBOSE printf( "%d)     GDC - Timestamp:%u\n",
834                           lineNmb,
835                           currTimestamp );
836     } else {
837       fprintf( stderr,
838                "%s: line:%d GDC declaration, unknown keyword \"%s\"\n",
839                myName,
840                lineNmb,
841                keyword );
842       exit( 1 );
843     }  
844   }
845 } /* End of parseGdc */
846
847 void parseLdc( char * const line ) {
848   char *p;
849   char *keyword;
850
851   p = line;
852   while ( (keyword = strtok_r( p, " \t", &p )) != NULL ) {
853     if ( strcasecmp( "id", keyword ) == 0 ) {
854       char *idNum;
855
856       if ( (idNum = strtok_r( p, " \t", &p )) == NULL ) {
857         fprintf( stderr,
858                  "%s: line:%d LDC declaration, ID needed",
859                  myName,
860                  lineNmb );
861         exit( 1 );
862       }
863       int inCurrLdcId;
864       if ( sscanf( idNum, "%d", &inCurrLdcId ) != 1 ) {
865         fprintf( stderr,
866                  "%s: line:%d LDC declaration, numeric ID needed (%s)",
867                  myName,
868                  lineNmb,
869                  idNum );
870         exit( 1 );
871       }
872       currLdcId = (eventLdcIdType)inCurrLdcId;
873       DBG_VERBOSE printf( "%d)     LDC - ID:%d\n",
874                           lineNmb,
875                           currLdcId );
876     } else {
877       fprintf( stderr,
878                "%s: line:%d LDC declaration, unknown keyword \"%s\"\n",
879                myName,
880                lineNmb,
881                keyword );
882       exit( 1 );
883     }  
884   }
885 } /* End of parseLdc */
886
887 void parseRules() {
888   char line[ 1025 ];
889
890   currLdcId = HOST_ID_MIN;
891   currGdcId = HOST_ID_MIN;
892   currDetPattern = 0;
893   currTimestamp = 0;
894
895   for ( lineNmb = 1; !feof( stdin ); lineNmb++ ) {
896     getLine( line, sizeof(line) );
897     if ( strlen(line) != 0 ) {
898       char *p;
899       char *keyword;
900
901       if ( (keyword = strtok_r( line, " \t", &p )) != NULL ) {
902         DBG_VERBOSE printf( "%d)   Keyword:\"%s\"\n", lineNmb, keyword );
903         if ( strcasecmp( "gdc", keyword ) == 0 ) {
904           if ( workingAs != gdc && workingAs != unknown ) {
905             fprintf( stderr,
906                      "%s: line:%d GDC found when working in non-GDC mode (e.g. as a LDC)\n",
907                      myName, lineNmb );
908             exit( 1 );
909           }
910           workingAs = gdc;
911           parseGdc( p );
912           createNewEvent();
913           currLdcId = HOST_ID_MIN;
914           currLdc = NULL;
915           currEquipmentId = 0;
916         } else if ( strcasecmp( "ldc", keyword ) == 0 ) {
917           if ( workingAs != gdc && workingAs != ldc && workingAs != unknown ) {
918             fprintf( stderr,
919                      "%s: line:%d LDC found when working in non-LDC/GDC mode\n",
920                      myName, lineNmb );
921             exit( 1 );
922           }
923           if ( workingAs == unknown ) workingAs = ldc;
924           parseLdc( p );
925           if ( workingAs == ldc ) {
926             createNewEvent();
927             currEquipmentId = 0;
928           } else {
929             createNewLdcEvent();
930             handleLdc( currLdcId );
931             currLdcId++;
932           }
933           currEvent = NULL;
934         } else if ( strncasecmp( "equ", keyword, 3 ) == 0 ) {
935           if ( workingAs == unknown
936             || (workingAs == ldc && currLdc == NULL )
937             || (workingAs == gdc && currGdc == NULL ) ) {
938             fprintf( stderr,
939                      "%s: line:%d Unexpected EQUIPMENT declaration (LDC or GDC needed first)\n",
940                      myName,
941                      lineNmb );
942             exit( 1 );
943           }
944           parseEquipment( p );
945           currEquipmentId++;
946         } else {
947           fprintf( stderr,
948                    "%s: line:%d Parse error in \"%s\" unknown keyword\n",
949                    myName,
950                    lineNmb,
951                    keyword );
952           exit( 1 );
953         }
954       }
955     }
956   } while ( !feof( stdin ) ) {}
957   lineNmb -= 2;
958
959   DBG_VERBOSE {
960     printf( "End of parse: %d line%s found\n",
961             lineNmb,
962             lineNmb != 1 ? "s" : "" );
963     printf( "Working as %s\n",
964             workingAs == gdc ? "GDC" :
965              workingAs == ldc ? "LDC" :
966               "UNKNOWN" );
967     if ( workingAs == gdc ) {
968       struct ldcDescriptorStruct *ldc;
969
970       printf( "LDCs (%d):", numOfLdcs );
971       for ( ldc = ldcsHead; ldc != NULL; ldc = ldc->next ) {
972         printf( " %d", ldc->id );
973       }
974       printf( "\n" );
975     }
976     dumpEvents();
977   }
978
979   if ( workingAs == ldc ) {
980     assert( ldcsHead == ldcsTail );
981     assert( ldcsTail == NULL );
982   }
983
984   if ( workingAs == gdc ) {
985     struct ldcDescriptorStruct *ldc;
986
987     assert( ldcsHead != NULL );
988     assert( ldcsTail != NULL );
989     assert( ldcsTail->next == NULL );
990     for ( ldc = ldcsHead; ldc->next != NULL; ldc = ldc->next ) {}
991     assert ( ldc == ldcsTail );
992   }
993
994   if ( workingAs == unknown ) {
995     DBG_VERBOSE printf( "Empty configuration: nothing to do!\n" );
996     exit( 0 );
997   }
998
999   assert( (eventsHead == NULL && eventsTail == NULL)
1000        || (eventsHead != NULL && eventsTail != NULL) );
1001 } /* End of parseRules */
1002
1003 void initEvent( struct eventHeaderStruct * const ev ) {
1004   memset( ev, 0, sizeof( *ev ) );
1005
1006   ev->eventMagic = EVENT_MAGIC_NUMBER;
1007   ev->eventHeadSize = EVENT_HEAD_BASE_SIZE;
1008   ev->eventVersion = EVENT_CURRENT_VERSION;
1009   ev->eventRunNb = currRunNb;
1010   ZERO_EVENT_ID( ev->eventId );
1011   ZERO_TRIGGER_PATTERN( ev->eventTriggerPattern );
1012   ZERO_DETECTOR_PATTERN( ev->eventDetectorPattern );
1013   RESET_ATTRIBUTES( ev->eventTypeAttribute );
1014   if ( workingMode == collider )
1015     SET_SYSTEM_ATTRIBUTE( ev->eventTypeAttribute, ATTR_ORBIT_BC );
1016   ev->eventLdcId = VOID_ID;
1017   ev->eventGdcId = VOID_ID;
1018 } /* End of initEvent */
1019
1020 int Swap(int x)
1021 {
1022    // Swap the endianess of the integer value 'x'
1023
1024    return (((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) <<  8) |
1025            ((x & 0x00ff0000U) >>  8) | ((x & 0xff000000U) >> 24));
1026 }
1027
1028 void outputEvent( const void * const ev,
1029                   const int size ) {
1030   int done;
1031
1032   DBG_VERBOSE {
1033     const long32 * const v = (long32 *)ev; 
1034     printf( "Writing %d bytes @ %p (%d)\n", size, ev, *v );
1035   }
1036
1037   // .............................Test endianess..............................
1038   int temp = 1;
1039   char* ptemp = (char*) &temp;
1040
1041   if (ptemp[0]!=1) { // Mac platform: ptemp != 1..............................................................................
1042      int  bufSize= size; if (bufSize > (int) sizeof(eventHeaderStruct)) { bufSize = sizeof(eventHeaderStruct); }
1043      char* evTemp = (char*) malloc (bufSize);
1044      memcpy(evTemp, ev, bufSize);
1045
1046      if ((bufSize % sizeof(int)) != 0) {
1047             fprintf( stderr, "%s: size of the input buffer ev is not multiple of 4 (size = %d)\n", myName, bufSize);
1048             exit( 1 );
1049           }
1050      else {
1051             // Invert header to evTemp.....................................................
1052             int* buf = (int*) evTemp; 
1053             for (int i=0; i < (int) (bufSize / sizeof(int)); i++, buf++) {
1054                  int value = Swap(*buf); 
1055                  memcpy(evTemp + (i * sizeof(int)), &value, sizeof(int)); 
1056             }
1057
1058             // Write inverted header to file...............................................
1059             if ((done = fwrite( evTemp, bufSize, 1, outF )) != 1 ) {
1060                  fprintf( stderr, "%s: failed to write inverted header. event size:%d bytes, errno:%d (%s)\n", myName, size, errno, strerror( errno ) );
1061                  exit( 1 );
1062             }
1063
1064             if (size > bufSize) {  // Still theraw-data payload to write (but not inverted, since it is inverted eariler).............
1065                 if ((done = fwrite( (char*)ev + bufSize, size - bufSize, 1, outF )) != 1 ) {
1066                     fprintf( stderr, "%s: failed to write additional event size:%d bytes, errno:%d (%s)\n", myName, size, errno, strerror( errno ) );
1067                     exit( 1 );
1068                }
1069             }
1070      }
1071      free(evTemp);
1072   }
1073   else {             // Intel platform: ptemp == 1............................................................................
1074      if ((done = fwrite( ev, size, 1, outF )) != 1 ) {
1075           fprintf( stderr, "%s: failed to write event size:%d bytes, errno:%d (%s)\n", myName, size, errno, strerror( errno ) );
1076           exit( 1 );
1077      }
1078   }
1079 } /* End of outputEvent */
1080
1081 void createSorAndEor( const int sor ) {
1082   unsigned char event[ 1000 ];
1083   struct eventHeaderStruct *ev;
1084   struct eventHeaderStruct sev;
1085
1086   assert( workingAs == ldc || workingAs == gdc );
1087
1088   if ( !createSorEor ) return;
1089   ev = (struct eventHeaderStruct *)event;
1090   initEvent( ev );
1091   ev->eventSize = sizeof( event );
1092   ev->eventType = sor ? START_OF_RUN : END_OF_RUN;
1093   if ( workingMode == fixedTarget )
1094     LOAD_RAW_EVENT_ID( ev->eventId, 0, 0, 0 );
1095   else
1096     LOAD_EVENT_ID( ev->eventId, 0, 0, 0 );
1097   SET_SYSTEM_ATTRIBUTE( ev->eventTypeAttribute, ATTR_P_START );
1098
1099   if ( workingAs == ldc ) {
1100     currLdc = (struct ldcEventDescriptorStruct *)eventsHead;
1101   }
1102   if ( workingAs == gdc ) {
1103     initEvent( &sev );
1104     sev.eventGdcId = currGdcId;
1105     ev->eventGdcId = currGdcId;
1106     currGdc = (struct gdcEventDescriptorStruct *)eventsHead;
1107     currLdc = currGdc->head;
1108   }
1109   ev->eventLdcId = currLdc->id;
1110
1111   if ( workingAs == ldc ) {
1112     outputEvent( ev, ev->eventSize );
1113   }
1114   if ( workingAs == gdc ) {
1115     struct ldcDescriptorStruct *ldc;
1116
1117     sev.eventSize = sizeof( sev ) + numOfLdcs * ev->eventSize;
1118     sev.eventType = sor ? START_OF_RUN : END_OF_RUN ;
1119     COPY_EVENT_ID( ev->eventId, sev.eventId );
1120     COPY_SYSTEM_ATTRIBUTES( ev->eventTypeAttribute, sev.eventTypeAttribute );
1121     SET_SYSTEM_ATTRIBUTE( sev.eventTypeAttribute, ATTR_SUPER_EVENT );
1122     outputEvent( &sev, sizeof( sev ) );
1123
1124     ev->eventGdcId = currGdcId;
1125     for ( ldc = ldcsHead; ldc != NULL; ldc = ldc->next ) {
1126       ev->eventLdcId = ldc->id;
1127       outputEvent( ev, ev->eventSize );
1128     }
1129   }
1130
1131   ADD_EVENT_ID( ev->eventId, oneEventDelta );
1132   ev->eventSize = ev->eventSize / 2;
1133   ev->eventType = sor ? START_OF_RUN_FILES : END_OF_RUN_FILES;
1134   CLEAR_SYSTEM_ATTRIBUTE( ev->eventTypeAttribute, ATTR_P_START );
1135   if ( workingAs == ldc ) {
1136     outputEvent( ev, ev->eventSize );
1137   }
1138   if ( workingAs == gdc ) {
1139     struct ldcDescriptorStruct *ldc;
1140
1141     sev.eventSize = ev->eventSize;
1142     sev.eventType = sor ? START_OF_RUN_FILES : END_OF_RUN_FILES;
1143     COPY_EVENT_ID( ev->eventId, sev.eventId );
1144     COPY_SYSTEM_ATTRIBUTES( ev->eventTypeAttribute, sev.eventTypeAttribute );
1145     CLEAR_SYSTEM_ATTRIBUTE( sev.eventTypeAttribute, ATTR_SUPER_EVENT );
1146     outputEvent( &sev, sizeof( sev ) );
1147     outputEvent( ev, ev->eventSize - sizeof( sev ) );
1148
1149     sev.eventSize = sizeof( sev ) + ev->eventSize;
1150     sev.eventType = sor ? START_OF_RUN_FILES : END_OF_RUN_FILES;
1151     COPY_EVENT_ID( ev->eventId, sev.eventId );
1152     COPY_SYSTEM_ATTRIBUTES( ev->eventTypeAttribute, sev.eventTypeAttribute );
1153     SET_SYSTEM_ATTRIBUTE( sev.eventTypeAttribute, ATTR_SUPER_EVENT );
1154
1155     ev->eventGdcId = currGdcId;
1156     for ( ldc = ldcsHead; ldc != NULL; ldc = ldc->next ) {
1157       outputEvent( &sev, sizeof( sev ) );
1158       ev->eventLdcId = ldc->id;
1159       outputEvent( ev, ev->eventSize );
1160     }
1161   }
1162
1163   ADD_EVENT_ID( ev->eventId, oneEventDelta );
1164   ev->eventSize = sizeof( *ev );
1165   ev->eventType = sor ? START_OF_RUN : END_OF_RUN;
1166   SET_SYSTEM_ATTRIBUTE( ev->eventTypeAttribute, ATTR_P_END );
1167   if ( workingAs == ldc ) {
1168     outputEvent( ev, ev->eventSize );
1169   }
1170   if ( workingAs == gdc ) {
1171     struct ldcDescriptorStruct *ldc;
1172
1173     sev.eventSize = sizeof( sev ) + numOfLdcs * ev->eventSize;
1174     sev.eventType = sor ? START_OF_RUN : END_OF_RUN;
1175     COPY_EVENT_ID( ev->eventId, sev.eventId );
1176     COPY_SYSTEM_ATTRIBUTES( ev->eventTypeAttribute, sev.eventTypeAttribute );
1177     SET_SYSTEM_ATTRIBUTE( sev.eventTypeAttribute, ATTR_SUPER_EVENT );
1178
1179     outputEvent( &sev, sizeof( sev ) );
1180
1181     for ( ldc = ldcsHead; ldc != NULL; ldc = ldc->next ) {
1182       ev->eventLdcId = ldc->id;
1183       outputEvent( ev, ev->eventSize );
1184     }
1185   }
1186 } /* End of createSorEor */
1187
1188 void createSor() {
1189   createSorAndEor( TRUE );
1190 } /* End of createSor */
1191
1192 void createEor() {
1193   createSorAndEor( FALSE );
1194 } /* End of createEor */
1195
1196 void loadCdh( struct commonDataHeaderStruct * const cdh,
1197                      eventIdType            * const eventId,
1198                      equipmentIdType id ) {
1199   if ( !handleCDH ) return;
1200
1201   // CTP raw-data does not contain CDH
1202   if ( id == 4352) return;
1203
1204   if ( gotAliceTrigger ) {
1205     cdh->cdhEventId1 = EVENT_ID_GET_BUNCH_CROSSING( *eventId );
1206     cdh->cdhEventId2 = EVENT_ID_GET_ORBIT( *eventId );
1207   } else {
1208     cdh->cdhEventId1 = 0;
1209     cdh->cdhEventId2 = EVENT_ID_GET_NB_IN_RUN( *eventId );
1210   }
1211   cdh->cdhMiniEventId = cdh->cdhEventId1;
1212 }
1213 void decodeCDH( struct ldcEventDescriptorStruct       * const ldc,
1214                 const struct payloadDescriptorStruct  * const payloadDesc,
1215                 equipmentIdType id );
1216
1217 void createEvent( void ) {
1218   assert( workingAs == ldc || workingAs == gdc );
1219
1220   /* Step 1: load all buffers (if needed) and compose the GDC/LDC headers */
1221   if ( workingAs == gdc ) {
1222     struct ldcEventDescriptorStruct *ldc;
1223
1224     for( ldc = currGdc->head; ldc != NULL; ldc = ldc->next ) {
1225       COPY_EVENT_ID( currEventId, ldc->header.eventId );
1226     }
1227     COPY_EVENT_ID( currEventId, currGdc->header.eventId );
1228
1229     for( ldc = currGdc->head; ldc != NULL; ldc = ldc->next ) {
1230       struct equipmentEventDescriptorStruct *eq;
1231       int n;
1232
1233       for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
1234         if ( !bufferData ) {
1235           loadBuffer( eq->payload );
1236           decodeCDH( ldc, eq->payload, eq->id );
1237         }
1238         loadCdh( (struct commonDataHeaderStruct*)eq->payload->data,
1239                  &currEventId,
1240                  eq->id);
1241       }
1242
1243       if ( !currGdc->loaded ) {
1244         for ( n = 0; n != EVENT_TRIGGER_PATTERN_WORDS; n++ )
1245           currGdc->header.eventTriggerPattern[n] |= ldc->header.eventTriggerPattern[n];
1246         for ( n = 0; n != EVENT_DETECTOR_PATTERN_WORDS; n++ )
1247           currGdc->header.eventDetectorPattern[n] |= ldc->header.eventDetectorPattern[n];
1248         for ( n = 0; n != ALL_ATTRIBUTE_WORDS; n++ )
1249           currGdc->header.eventTypeAttribute[n] |= ldc->header.eventTypeAttribute[n];
1250         currGdc->loaded = TRUE;
1251       }
1252     }
1253     cdhRef = NULL;
1254   } else if ( workingAs == ldc ) {
1255     struct equipmentEventDescriptorStruct *eq;
1256
1257     COPY_EVENT_ID( currEventId, currLdc->header.eventId );
1258
1259     for ( eq = currLdc->head; eq != NULL; eq = eq->next ) {
1260       if ( !bufferData ) {
1261         loadBuffer( eq->payload );
1262         decodeCDH( currLdc, eq->payload, eq->id );
1263       }
1264       loadCdh( (struct commonDataHeaderStruct*)eq->payload->data,
1265                &currEventId,
1266                eq->id);
1267       currLdc->loaded = TRUE;
1268     }
1269     cdhRef = NULL;
1270   }
1271   ADD_EVENT_ID( currEventId, oneEventDelta );
1272
1273   /* Step 2: output the event */
1274   if ( workingAs == gdc ) {
1275     struct ldcEventDescriptorStruct *ldc;
1276
1277     outputEvent( &currGdc->header, sizeof( currGdc->header ) );
1278
1279     for( ldc = currGdc->head; ldc != NULL; ldc = ldc->next ) {
1280       struct equipmentEventDescriptorStruct *eq;
1281
1282       outputEvent( &ldc->header, sizeof( ldc->header ) );
1283
1284       for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
1285         outputEvent( &eq->header, sizeof( eq->header ) );
1286         outputEvent( eq->payload->data, eq->payload->size );
1287         if ( !bufferData ) unloadBuffer( eq->payload );
1288       }
1289     }
1290     if ( (currGdc = currGdc->next) == NULL )
1291       currGdc = (struct gdcEventDescriptorStruct *)eventsHead;
1292   } else if ( workingAs == ldc ) {
1293     struct equipmentEventDescriptorStruct *eq;
1294
1295     outputEvent( &currLdc->header, sizeof( currLdc->header ) );
1296
1297     for ( eq = currLdc->head; eq != NULL; eq = eq->next ) {
1298       outputEvent( &eq->header, sizeof( eq->header ) );
1299       outputEvent( eq->payload->data, eq->payload->size );
1300       if ( !bufferData ) unloadBuffer( eq->payload );
1301     }
1302     if ( (currLdc = currLdc->next) == NULL )
1303       currLdc = (struct ldcEventDescriptorStruct *)eventsHead;
1304   }
1305 } /* End of createEvent */
1306
1307 void createEvents() {
1308   int eventNum = 0;
1309
1310   currGdc = (struct gdcEventDescriptorStruct *)eventsHead;
1311   currLdc = (struct ldcEventDescriptorStruct *)eventsHead;
1312   currEvent = NULL;
1313
1314   createSor();
1315   for ( eventNum = 0;
1316         eventNum != numOfEvents && numOfEvents != 0;
1317         eventNum++ ) {
1318     createEvent();
1319   }
1320   createEor();
1321 } /* End of createEvents */
1322
1323 int usage() {
1324   fprintf( stderr,
1325            "Usage: %s [-?][-d][-i definitionFile][-o outputFile][-# numOfEvents][-s][-F|-C]\n\
1326    -?                  This text\n\
1327    -v                  Print version ID and exit\n\
1328    -d                  Enable debug (repeat for more verbosity)\n\
1329    -i definitionFile   File with the description of the events to create (default: stdin)\n\
1330    -o outputFile       File used to store events (default: stdout)\n\
1331    -# numOfEvents      Number of events to generate (default: 1 event)\n\
1332    -s                  Do not generate SOR/EOR files (valid only for GDCs)\n\
1333    -F/-C               Working in Fixed Target (F) or Collider (C) mode\n\
1334    -c                  Handles CDH\n\
1335    -D                  Direct disc access (no buffering)\n",
1336            myName );
1337   return 1;
1338 } /* End of usage */
1339
1340 void parseArgs( int argc, char **argv ) {
1341   int arg = 1;
1342   int inFileName = -1;
1343   int outFileName = -1;
1344
1345   myName = argv[0] ;
1346   while ( arg < argc ) {
1347     if ( strcmp( "-?", argv[ arg ] ) == 0 ) {
1348       usage();
1349       exit( 0 );
1350     }
1351     if ( strcmp( "-i", argv[ arg ] ) == 0 ) {
1352       if ( ++arg == argc ) exit( usage() );
1353       inFileName = arg;
1354       if ( freopen( argv[arg], "r", stdin ) == NULL ){
1355         fprintf( stderr,
1356                  "%s: failed to open input definition \"%s\" errno:%d ",
1357                  myName, argv[arg], errno );
1358         perror( "" );
1359         exit( 1 );
1360       }
1361     } else if ( strcmp( "-v", argv[ arg ] ) == 0 ) {
1362       printf( "%s\n", fileHandlerIdent );
1363       exit( 0 );
1364     } else if ( strcmp( "-o", argv[ arg ] ) == 0 ) {
1365       if ( ++arg == argc ) exit( usage() );
1366       outFileName = arg;
1367     } else if ( strcmp( "-#", argv[ arg ] ) == 0 ) {
1368       int n;
1369
1370       if ( ++arg == argc ) exit( usage() );
1371       if ( sscanf( argv[ arg ], "%d", &n ) != 1 ) exit( usage() );
1372       if ( n < 0 ) exit( usage() );
1373       numOfEvents = n;
1374     } else if ( strcmp( "-s", argv[ arg ] ) == 0 ) {
1375       createSorEor = FALSE;
1376     } else if ( strcmp( "-F", argv[ arg ] ) == 0 ) {
1377       workingMode = fixedTarget;
1378     } else if ( strcmp( "-C", argv[ arg ] ) == 0 ) {
1379       workingMode = collider;
1380     } else if ( strcmp( "-d", argv[ arg ] ) == 0 ) {
1381       debug++;
1382     } else if ( strcmp( "-c", argv[ arg ] ) == 0 ) {
1383       handleCDH = TRUE;
1384     } else if ( strcmp( "-D", argv[ arg ] ) == 0 ) {
1385       bufferData = FALSE;
1386     } else if ( strcmp( "-run", argv[ arg ] ) == 0 ) {
1387       int runnumber;
1388       if ( ++arg == argc ) exit( usage() );
1389       if ( sscanf( argv[ arg ], "%d", &runnumber ) != 1 ) exit( usage() );
1390       if ( runnumber < 0 ) exit( usage() );
1391       currRunNb = runnumber;
1392     } else {
1393       fprintf( stderr, "%s: Unknown switch \"%s\"\n", myName, argv[argc] );
1394       exit( usage() );
1395     }
1396     arg++;
1397   }
1398
1399   if ( workingMode == fixedTarget )
1400     LOAD_RAW_EVENT_ID( oneEventDelta, 1, 0, 1 );
1401   else
1402     LOAD_EVENT_ID( oneEventDelta, 0, 0, 1 );
1403   ZERO_EVENT_ID( currEventId );
1404
1405   DBG_VERBOSE {
1406     printf( "Configuration:\n" );
1407     printf( "  Debug level: %d\n", debug );
1408     printf( "  Configuration: %s\n",
1409             inFileName == -1 ? "stdin" : argv[ inFileName ] );
1410     printf( "  Output: %s\n",
1411             outFileName == -1 ? "stdout" : argv[ outFileName ] );
1412     printf( "  Working mode: %s\n",
1413             workingMode == fixedTarget ? "fixed target" : "collider" );
1414     printf( "  Number of events: %d\n", numOfEvents );
1415     printf( "  %s SOR/EOR files\n",
1416             createSorEor ? "Create" : "Do not create" );
1417     printf( "  CDH handling: %s\n",
1418             handleCDH ? "enabled" : "disabled" );
1419     printf( "  data buffering: %s\n",
1420             bufferData ? "enabled" : "DISABLED" );
1421   }
1422
1423   if ( outFileName == -1 ) {
1424     DBG_BASE
1425       printf( "No more trace information from this point...\n" );
1426     debug = 0;
1427     outF = stdout;
1428   } else {
1429     if ( ( outF = fopen( argv[ outFileName ], "w" ) ) == NULL ) {
1430       fprintf( stderr,
1431                "%s: failed to open output file \"%s\" for writing, errno:%d (%s)\n",
1432                myName,
1433                argv[ outFileName ],
1434                errno,
1435                strerror( errno ) );
1436       exit( 1 );
1437     }
1438     DBG_DETAILED
1439       printf( "Output file \"%s\" opened OK for writing\n",
1440               argv[ outFileName ] );
1441   }
1442 } /* End of parseArgs */
1443 void initEquipment( struct equipmentHeaderStruct * const eq ) {
1444   memset( eq, 0, sizeof( *eq ) );
1445   RESET_ATTRIBUTES( eq->equipmentTypeAttribute );
1446   eq->equipmentBasicElementSize = 4;
1447 } /* End of initEquipment */
1448
1449 void decodeCDH(       struct ldcEventDescriptorStruct * const ldc,
1450                 const struct payloadDescriptorStruct  * const payloadDesc,
1451                       equipmentIdType id ) {
1452   if ( handleCDH && 
1453        id != 4352 ) {
1454     struct commonDataHeaderStruct *cdh;
1455     static int softwareTriggerIndicator = FALSE;
1456     int attr;
1457     int trig;
1458
1459     if ( payloadDesc->size < CDH_SIZE ) {
1460       fprintf( stderr,
1461                "%s: payload too small got:%d CDH:%d\n",
1462                myName,
1463                payloadDesc->size,
1464                CDH_SIZE );
1465       exit( 1 );
1466     }
1467     if ( (cdh = (struct commonDataHeaderStruct *)payloadDesc->data) != NULL ) {
1468       if ( cdh->cdhVersion != CDH_VERSION ) {
1469         fprintf( stderr,
1470                  "%s: CDH version mismatch expected:%d got:%d\n",
1471                  myName,
1472                  CDH_VERSION,
1473                  cdh->cdhVersion );
1474         exit( 1 );
1475       }
1476       if ( cdhRef == NULL ) {
1477         cdhRef = cdh;
1478 #define CDH_TRIGGER_INFORMATION_UNAVAILABLE_MASK (1<<CDH_TRIGGER_INFORMATION_UNAVAILABLE_BIT)
1479         gotAliceTrigger = (cdhRef->cdhStatusErrorBits & CDH_TRIGGER_INFORMATION_UNAVAILABLE_MASK) == 0;
1480         if ( gotAliceTrigger && workingMode == fixedTarget ) {
1481           fprintf( stderr,
1482                    "%s: ALICE trigger and fixed target mode are not compatible.\n\
1483 Either work in Collider mode or set the trigger unavailable status bit in the CDH.\n",
1484                    myName );
1485           exit( 1 );
1486         }
1487         if ( gotAliceTrigger ) {
1488           if ( (cdh->cdhL1TriggerMessage & 0x40) != 0 ) {
1489             fprintf( stderr,
1490                      "%s: CDH is a calibration trigger (unsupported) L1TriggerMessage:0x%x\n",
1491                      myName, cdh->cdhL1TriggerMessage );
1492             exit( 1 );
1493           }
1494           if ( (cdh->cdhL1TriggerMessage & 0x01) != 0 ) {
1495             softwareTriggerIndicator = TRUE;
1496           }
1497           if ( softwareTriggerIndicator ) {
1498             switch ((cdh->cdhL1TriggerMessage >> 2) & 0xF) {
1499             case 0xD:
1500             case 0xC:
1501             case 0xB:
1502             case 0xA:
1503             case 0x9:
1504               break;
1505             case 0xF:
1506               /* L1SwC bit = on, Clt bit = off, RoC[4..1] = 0xF --> END_OF_DATA */ 
1507             case 0xE:
1508               /* L1SwC bit = on, Clt bit = off, RoC[4..1] = 0xE0 --> START_OF_DATA */
1509             case 0x8:
1510               /*  L1SwC bit = on, Clt bit = off, RoC[4] = 1, but not 0xE or 0xF
1511                   --> SYSTEM_SOFTWARE_TRIGGER_EVENT */
1512             default:
1513               /*  L1SwC bit = on, Clt bit = off, RoC[4] = 0
1514                   --> DETECTOR_SOFTWARE_TRIGGER_EVENT */
1515               fprintf( stderr,
1516                        "%s: CDH trigger SOD/EOD/SST/DST (unsupported) \
1517 L1TriggerMessage:0x%x ALICETrigger:%s\n",
1518                        myName,
1519                        cdh->cdhL1TriggerMessage,
1520                        gotAliceTrigger ? "yes" : "no" );
1521               exit( 1 );
1522             }
1523           }
1524         }
1525       } else {
1526         if ( (cdh->cdhStatusErrorBits & CDH_TRIGGER_INFORMATION_UNAVAILABLE_MASK) !=
1527              (cdhRef->cdhStatusErrorBits & CDH_TRIGGER_INFORMATION_UNAVAILABLE_MASK) ) {
1528           fprintf( stderr,
1529                    "%s: CDH coherency check failed. \
1530 Trigger information reference:%savailable current:%savailable\n",
1531                    myName,
1532                    (cdhRef->cdhStatusErrorBits & CDH_TRIGGER_INFORMATION_UNAVAILABLE_MASK) == 0 ? "UN" : "",
1533                    (cdh->cdhStatusErrorBits & CDH_TRIGGER_INFORMATION_UNAVAILABLE_MASK) == 0 ? "UN" : "" );
1534           exit( 1 );
1535         }
1536         if ( gotAliceTrigger ) {
1537           if ( cdhRef->cdhL1TriggerMessage != cdh->cdhL1TriggerMessage ) {
1538             fprintf( stderr,
1539                      "%s: CDH coherency check failed. \
1540 L1 trigger message reference:0x%x current:0x%x\n",
1541                      myName,
1542                      cdhRef->cdhL1TriggerMessage,
1543                      cdh->cdhL1TriggerMessage );
1544             exit( 1 );
1545           }
1546           if ( cdh->cdhParticipatingSubDetectors != cdhRef->cdhParticipatingSubDetectors ) {
1547             fprintf( stderr,
1548                      "%s: CDH coherency check failed. \
1549 ParticipatingSubDetectors reference:0x%x current:0x%x\n",
1550                      myName,
1551                      cdhRef->cdhParticipatingSubDetectors,
1552                      cdh->cdhParticipatingSubDetectors );
1553             exit( 1 );
1554           }
1555           if ( cdh->cdhTriggerClassesLow  != cdhRef->cdhTriggerClassesLow
1556                || cdh->cdhTriggerClassesHigh != cdhRef->cdhTriggerClassesHigh ) {
1557             fprintf( stderr,
1558                      "%s: CDH coherency check failed. \
1559 TriggerClassesHigh/Low reference:0x%x-%x current:0x%x-%x\n",
1560                      myName,
1561                      cdhRef->cdhTriggerClassesHigh, cdhRef->cdhTriggerClassesLow,
1562                      cdh   ->cdhTriggerClassesHigh, cdh   ->cdhTriggerClassesLow  );
1563             exit( 1 );
1564           }
1565           if ( cdh->cdhBlockLength != 0xffffffff ) {
1566             if ( (unsigned)payloadDesc->size !=  cdh->cdhBlockLength ) {
1567               fprintf( stderr,
1568                        "%s: CDH coherency check failed. \
1569 Payload size:%d (0x%08x) CDH block length:%d (0x%08x)\n",
1570                        myName,
1571                        payloadDesc->size, payloadDesc->size,
1572                        cdh->cdhBlockLength, cdh->cdhBlockLength );
1573               exit( 1 );
1574             }
1575           }
1576           if ( cdh->cdhRoiLow  != cdhRef->cdhRoiLow
1577                || cdh->cdhRoiHigh != cdhRef->cdhRoiHigh ) {
1578             fprintf( stderr,
1579                      "%s: CDH coherency check failed. \
1580 RoiHigh/Low reference:0x%x-%x current:0x%x-%x\n",
1581                      myName,
1582                      cdhRef->cdhRoiHigh, cdhRef->cdhRoiLow,
1583                      cdh   ->cdhRoiHigh, cdh   ->cdhRoiLow  );
1584             exit( 1 );
1585           }
1586         }
1587         if ( cdh->cdhMBZ0 != 0
1588              || cdh->cdhMBZ1 != 0
1589              || cdh->cdhMBZ2 != 0
1590              || cdh->cdhMBZ3 != 0 ) {
1591           fprintf( stderr,
1592                    "%s: CDH check failed. MBZ0:0x%x MBZ1:0x%x MBZ2:0x%x MBZ3:0x%x\n",
1593                    myName,
1594                    cdh->cdhMBZ0, cdh->cdhMBZ1, cdh->cdhMBZ2, cdh->cdhMBZ3 );
1595           exit( 1 );
1596         }
1597       }
1598       for ( attr = 0; attr != 8; attr++ ) {
1599         if ( (cdh->cdhBlockAttributes & (1<<attr)) != 0 ) {
1600           SET_USER_ATTRIBUTE( ldc->header.eventTypeAttribute, attr );
1601         }
1602       }
1603       for ( trig = 0; trig != 32; trig++ ) {
1604         if ( (cdh->cdhTriggerClassesLow & (1<<trig)) != 0 ) {
1605           SET_TRIGGER_IN_PATTERN( ldc->header.eventTriggerPattern,
1606                                   trig );
1607         }
1608       }
1609       for ( trig = 0; trig != 18; trig++ ) {
1610         if ( (cdh->cdhTriggerClassesHigh & (1<<trig)) != 0 ) {
1611           SET_TRIGGER_IN_PATTERN( ldc->header.eventTriggerPattern,
1612                                   32+trig );
1613         }
1614       }
1615       if ( gotAliceTrigger )
1616         VALIDATE_TRIGGER_PATTERN( ldc->header.eventTriggerPattern );
1617     }
1618   }
1619 } /* End of decodeCDH */
1620
1621 void initEvents() {
1622   assert( workingAs == ldc || workingAs == gdc );
1623
1624   if ( workingAs == gdc ) {
1625     struct gdcEventDescriptorStruct *gdc;
1626
1627     for ( gdc = (struct gdcEventDescriptorStruct *)eventsHead;
1628           gdc != NULL;
1629           gdc = gdc->next ) {
1630       struct ldcEventDescriptorStruct *ldc;
1631
1632       initEvent( &gdc->header );
1633       gdc->header.eventSize = gdc->header.eventHeadSize;
1634       gdc->header.eventType = PHYSICS_EVENT;
1635       SET_SYSTEM_ATTRIBUTE( gdc->header.eventTypeAttribute, ATTR_SUPER_EVENT );
1636       gdc->header.eventGdcId = currGdcId;
1637       COPY_DETECTOR_PATTERN(&gdc->detPattern, gdc->header.eventDetectorPattern);
1638       gdc->header.eventTimestamp = gdc->timestamp;
1639       for ( ldc = gdc->head; ldc != NULL; ldc = ldc->next ) {
1640         struct equipmentEventDescriptorStruct *eq;
1641
1642         initEvent( &ldc->header );
1643         ldc->header.eventSize = ldc->header.eventHeadSize;
1644         ldc->header.eventType = PHYSICS_EVENT;
1645         ldc->header.eventGdcId = currGdcId;
1646         COPY_DETECTOR_PATTERN(&ldc->detPattern, ldc->header.eventDetectorPattern);
1647         ldc->header.eventTimestamp = ldc->timestamp;
1648         ldc->header.eventLdcId = ldc->id;
1649         for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
1650           initEquipment( &eq->header );
1651           eq->header.equipmentId = eq->id;
1652           if ( workingMode == collider )
1653             SET_SYSTEM_ATTRIBUTE( eq->header.equipmentTypeAttribute,
1654                                   ATTR_ORBIT_BC );
1655           eq->header.equipmentSize = eq->payload->size + sizeof( eq->header );
1656           ldc->header.eventSize += eq->header.equipmentSize;
1657           decodeCDH( ldc, eq->payload, eq->id );
1658           OR_ALL_ATTRIBUTES( eq->header.equipmentTypeAttribute,
1659                              ldc->header.eventTypeAttribute );
1660           OR_ALL_ATTRIBUTES( eq->header.equipmentTypeAttribute,
1661                              gdc->header.eventTypeAttribute );
1662         }
1663         gdc->header.eventSize += ldc->header.eventSize;
1664       }
1665       cdhRef = NULL;
1666     }
1667
1668     DBG_VERBOSE {
1669       printf( "Headers:\n" );
1670       for ( gdc = (struct gdcEventDescriptorStruct *)eventsHead;
1671             gdc != NULL;
1672             gdc = gdc->next ) {
1673         struct ldcEventDescriptorStruct *ldc;
1674         
1675         printf( "   GDC:%d size:%d vers:%08x\n",
1676                 currGdcId,
1677                 gdc->header.eventSize,
1678                 gdc->header.eventVersion);
1679         for ( ldc = gdc->head; ldc != NULL; ldc = ldc->next ) {
1680           struct equipmentEventDescriptorStruct *eq;
1681
1682           printf( "      LDC:%d size:%d vers:%08x\n",
1683                   ldc->id,
1684                   ldc->header.eventSize,
1685                   ldc->header.eventVersion );
1686           for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
1687             printf( "         EQ:%d size:%d %spayload:%d\n",
1688                     eq->id,
1689                     eq->header.equipmentSize,
1690                     eq->header.equipmentSize - sizeof( struct equipmentHeaderStruct ) == (unsigned)eq->payload->size ? "" : "-ERROR",
1691                     eq->payload->size );
1692           }
1693         }
1694       }
1695     }
1696   } else if ( workingAs == ldc ) {
1697     struct ldcEventDescriptorStruct *ldc;
1698
1699     for ( ldc = (struct ldcEventDescriptorStruct *)eventsHead;
1700           ldc != NULL;
1701           ldc = ldc->next ) {
1702       struct equipmentEventDescriptorStruct *eq;
1703
1704       initEvent( &ldc->header );
1705       ldc->header.eventSize = ldc->header.eventHeadSize;
1706       ldc->header.eventType = PHYSICS_EVENT;
1707       ldc->header.eventGdcId = VOID_ID;
1708       ldc->header.eventLdcId = ldc->id;
1709       for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
1710         initEquipment( &eq->header );
1711         eq->header.equipmentId = eq->id;
1712         if ( workingMode == collider )
1713           SET_SYSTEM_ATTRIBUTE( eq->header.equipmentTypeAttribute,
1714                                 ATTR_ORBIT_BC );
1715         eq->header.equipmentSize = eq->payload->size + sizeof( eq->header );
1716         ldc->header.eventSize += eq->header.equipmentSize;
1717         decodeCDH( ldc, eq->payload, eq->id );
1718         OR_ALL_ATTRIBUTES( eq->header.equipmentTypeAttribute,
1719                            ldc->header.eventTypeAttribute );
1720       }
1721       cdhRef = NULL;
1722     }
1723     DBG_VERBOSE {
1724       printf( "Headers:\n" );
1725       for ( ldc = (struct ldcEventDescriptorStruct *)eventsHead;
1726             ldc != NULL;
1727             ldc = ldc->next ) {
1728         struct equipmentEventDescriptorStruct *eq;
1729
1730         printf( "      LDC:%d size:%d vers:%08x\n",
1731                 ldc->id,
1732                 ldc->header.eventSize,
1733                 ldc->header.eventVersion );
1734         for ( eq = ldc->head; eq != NULL; eq = eq->next ) {
1735           printf( "         EQ:%d size:%d %spayload:%d\n",
1736                   eq->id,
1737                   eq->header.equipmentSize,
1738                   eq->header.equipmentSize - sizeof( struct equipmentHeaderStruct ) == (unsigned)eq->payload->size ? "" : "-ERROR",
1739                   eq->payload->size );
1740         }
1741       }
1742     }
1743   }
1744 } /* End of initEvents */
1745
1746 void initVars() {
1747   debug = 0;
1748   workingAs = unknown;
1749   workingMode = fixedTarget;
1750   ldcsHead = ldcsTail = NULL;
1751   eventsHead = eventsTail = NULL;
1752   currGdc = NULL;
1753   currLdc = NULL;
1754   currEvent = NULL;
1755   payloadsHead = payloadsTail = NULL;
1756   currRunNb = -1;
1757   numOfLdcs = 0;
1758   numOfEvents = 1;
1759   createSorEor = TRUE;
1760   handleCDH = FALSE;
1761   gotAliceTrigger = TRUE;
1762   bufferData=TRUE;
1763 } /* End of initVars */
1764
1765 int main( int argc, char **argv ) {
1766   initVars();
1767   parseArgs( argc, argv );
1768   parseRules();
1769   initEvents();
1770   createEvents();
1771   return 0;
1772 } /* End of main */