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