1
/*******************************************************************************
3
* mcfio_Sequential.c -- Utility routines for the McFast Monte-Carlo *
4
* Real Sequential routines, based on the RBIO package. *
6
* Copyright (c) 1995 Universities Research Association, Inc. *
7
* All rights reserved. *
9
* This material resulted from work developed under a Government Contract and *
10
* is subject to the following license: The Government retains a paid-up, *
11
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
12
* works, perform publicly and display publicly by or for the Government, *
13
* including the right to distribute to other Government contractors. Neither *
14
* the United States nor the United States Department of Energy, nor any of *
15
* their employees, makes any warranty, express or implied, or assumes any *
16
* legal liability or responsibility for the accuracy, completeness, or *
17
* usefulness of any information, apparatus, product, or process disclosed, or *
18
* represents that its use would not infringe privately owned rights. *
21
* Written by Paul Lebrun *
24
*******************************************************************************/
27
#include "mcfio_Sequential.h"
29
#include <sys/param.h>
30
#include <rpc/types.h>
31
#include <sys/types.h>
37
#include <floatingpoint.h>
42
#include "mcfio_Dict.h"
43
#include "mcfio_Util1.h"
44
#include "mcfio_Sequential.h"
53
int mcfioC_OpenReadSequential(char *device, char *vsn, int filenumber)
55
int i, jstr, idtmp, ntot, ll, iost, jfn, ldat, lrdat;
60
** Prolog, as in mcfio_Direct
62
if (McfStreamPtrList == NULL) mcfioC_Init();
63
if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
65
" mcfio_OpenReadSequential: Too many streams opened simultaneously.\n");
69
** Check that this device is not already in used, if so, check that the
70
** status is MCFIO_EOF, if so, assign the jstr to that stream.
72
for (i=0, jstr = -1; i<McfNumOfStreamActive; i++) {
73
if (McfStreamPtrList[i] != NULL) {
74
str = McfStreamPtrList[i];
75
if ((str->row == MCFIO_READ) && (str->dos == MCFIO_SEQUENTIAL)) {
76
if (strcmp(device, str->device) == 0) {
77
if (str->status != MCFIO_EOF)
78
mcfioC_CloseSequentialFile((i+1));
84
while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
85
if (McfStreamPtrList[i] == NULL) jstr=i;
90
" mcfio_OpenReadSequential: Internal error, please report \n");
94
** building the filename string for rbio. Note that we do not repeat the
95
** label if the device has already been opened prior to this call.
99
if (McfStreamPtrList[jstr] == NULL) {
100
ll = strlen(device) + strlen(vsn) + 40;
101
fileRbio = (char *) malloc (sizeof(char)*ll);
102
if (strcmp(vsn,"None") == 0)
103
sprintf(fileRbio,"%s:S=%d",
105
else if (strcmp(vsn,"Disk") == 0)
106
sprintf(fileRbio,"%s:UFORT", device);
108
sprintf(fileRbio,"%s:VSN=%s:S=%d",
109
device, vsn, filenumber);
110
ll = strlen(fileRbio);
111
rbfopen_(&jfn, fileRbio, "R", &iost, ll, 1);
113
ll = strlen(device) + 12;
114
fileRbio = (char *) malloc (sizeof(char)*ll);
115
sprintf(fileRbio,"%s:S=%d", device, filenumber);
116
ll = strlen(fileRbio);
117
rbopen_(&jfn, fileRbio, &iost, ll, 1);
122
" mcfio_OpenReadSequential: Problem opening device %s, \
123
VSN %s, file %d \n", device, vsn, filenumber);
127
if (McfStreamPtrList[jstr] == NULL) {
128
McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
129
str = McfStreamPtrList[jstr];
130
str->xdr = (XDR *) malloc(sizeof(XDR));
132
str->row = MCFIO_READ;
133
str->dos = MCFIO_SEQUENTIAL;
134
str->filename = NULL;
136
ll = strlen(device) + 1;
137
str->device = (char*) malloc(sizeof(char) * ll);
138
strcpy(str->device, device);
139
str->filenumber = filenumber;
140
ll = strlen(vsn) + 1;
141
str->vsn = (char*) malloc(sizeof(char) * ll);
142
strcpy(str->vsn, vsn);
143
str->minlrec = MCF_XDR_MINLREC;
144
if (strcmp(vsn,"Disk") == 0)
145
ll = MCF_XDR_MAXLREC;
147
rblklen_(&jfn, &ll, &iost);
156
str->filenumber = filenumber;
157
str->minlrec = MCF_XDR_MINLREC;
158
rblklen_(&jfn, &ll, &iost);
161
if (str->buffer != NULL) free(str->buffer);
162
if (str->buffer2 != NULL) free(str->buffer2);
167
** decode the first buffer, the Sequential header.
169
if (str->buffer == NULL) {
170
str->bufferSize = str->maxlrec;
171
str->buffer = (char *) malloc(sizeof(char) * (str->maxlrec + 1));
174
rbread_(&jfn, str->buffer, &ldat, &lrdat, &iost);
177
" mcfio_OpenReadSequential: Problem reading first record on \n device %s, \
178
VSN %s, file %d \n", device, vsn, filenumber);
179
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
180
rbfclose_(&jfn, &iost);
183
str->numWordsT += lrdat/4;
184
xdrmem_create(str->xdr, str->buffer, str->maxlrec, XDR_DECODE);
185
p1 = xdr_getpos(str->xdr);
187
str->status = MCFIO_BOF;
189
if (xdr_mcfast_fileheader(str->xdr, &idtmp,
190
&ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
192
"mcfio_OpenReadSequential: Unable to decode seqheader \n");
193
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
194
rbfclose_(&jfn, &iost);
197
if (idtmp != FILEHEADER) {
199
"mcfio_OpenReadSequential: First Structure not the file header \n");
202
" : Further accesses probably suspicious \n");
203
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
204
rbfclose_(&jfn, &iost);
207
xdr_setpos(str->xdr, p1);
208
str->currentPos = p1;
209
str->numWordsC += (ntot/4);
210
str->status = MCFIO_RUNNING;
211
if (str->ehead == NULL)
212
str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
213
str->ehead->dimBlocks = str->fhead->nBlocks;
214
str->ehead->blockIds = NULL;
215
str->ehead->ptrBlocks = NULL;
216
str->ehead->dimNTuples = str->fhead->nNTuples;
217
str->ehead->nTupleIds = NULL;
218
str->ehead->ptrNTuples = NULL;
219
McfNumOfStreamActive++;
225
int mcfioC_OpenWriteSequential(char *device, char *vsn, char *title,
226
char *comment, int numevts_pred,
227
int *blkIds, unsigned int nBlocks)
229
int i, jstr, idtmp, ntot, ll, iost, jfn, ldat, lwdat, filenumber;
234
** Prolog, as in mcfio_Direct
236
if (McfStreamPtrList == NULL) {
238
" mcfio_OpenWriteSequential: We will first initialize by calling mcfio_Init.\n");
241
if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
243
" mcfio_OpenWriteSequential: Too many streams opened simultaneously.\n");
247
** Check that this device is not already in used, if so, check that the
248
** status is MCFIO_EOF, if so, assign the jstr to that stream.
250
for (i=0, jstr = -1; i<McfNumOfStreamActive; i++) {
251
if (McfStreamPtrList[i] != NULL) {
252
str = McfStreamPtrList[i];
253
if ((str->row == MCFIO_WRITE) && (str->dos == MCFIO_SEQUENTIAL)) {
254
if (strcmp(device, str->device) == 0) {
255
if (str->status != MCFIO_EOF)
256
mcfioC_CloseSequentialFile((i+1));
262
while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
263
if (McfStreamPtrList[i] == NULL) jstr=i;
268
" mcfio_OpenWriteSequential: Internal error, please report \n");
271
if ((title != NULL) && (strlen(title) > 255)) {
273
" mcfio_OpenWriteSequential: Title is too long\n");
277
if ((comment != NULL) && (strlen(comment) > 255)) {
279
" mcfio_OpenWriteSequential: comment is too long\n");
284
** building the filename string for rbio
287
lwdat = MCF_XDR_MAXLREC;
288
if (McfStreamPtrList[jstr] == NULL) {
290
ll = strlen(device) + strlen(vsn) + 80; /* more than 10 digits for
291
** filenumber block length O.K.
293
fileRbio = (char *) malloc (sizeof(char)*ll);
294
if (strcmp(vsn,"None") == 0)
295
sprintf(fileRbio,"%s:D=mcfio_%d.dat:S=%d:F=U:B=%d",
296
device, filenumber, filenumber, lwdat);
297
else if (strcmp(vsn,"Disk") == 0)
298
sprintf(fileRbio,"%s:UFORT", device);
300
sprintf(fileRbio,"%s:D=mcfio_%d.dat:VSN=%s:S=%d:F=U:B=%d",
301
device, filenumber,vsn, filenumber, lwdat);
302
ll = strlen(fileRbio);
303
rbfopen_(&jfn, fileRbio, "W", &iost, ll, 1);
306
filenumber = str->filenumber;
307
ll = strlen(device) + 80;
308
fileRbio = (char *) malloc (sizeof(char)*ll);
309
sprintf(fileRbio,"%s:D=mcfio_%d.dat:S=%d:F=U:B=%d",
310
device, filenumber, filenumber, lwdat);
311
ll = strlen(fileRbio);
312
rbopen_(&jfn, fileRbio, &iost, ll, 1);
317
" mcfio_OpenWriteSequential: \n\
318
Problem opening device %s, \
319
VSN %s, file %d, Rbio status = \n", device, vsn, filenumber, iost);
323
if (McfStreamPtrList[jstr] == NULL) {
324
McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
325
str = McfStreamPtrList[jstr];
326
str->xdr = (XDR *) malloc(sizeof(XDR));
328
str->row = MCFIO_WRITE;
329
str->dos = MCFIO_SEQUENTIAL;
330
str->filename = NULL;
332
ll = strlen(device) + 1;
333
str->device = (char*) malloc(sizeof(char) * ll);
334
strcpy(str->device, device);
335
ll = strlen(vsn) + 1;
336
str->vsn = (char*) malloc(sizeof(char) * ll);
337
strcpy(str->vsn, vsn);
339
str->minlrec = MCF_XDR_MINLREC;
340
if (strcmp(vsn,"Disk") == 0)
341
ll = MCF_XDR_MAXLREC;
343
rblklen_(&jfn, &ll, &iost);
352
str->minlrec = MCF_XDR_MINLREC;
353
rblklen_(&jfn, &ll, &iost);
356
if (str->buffer != NULL) free(str->buffer);
357
if (str->buffer2 != NULL) free(str->buffer2);
362
** encode the first buffer, the file header.
364
if (str->buffer == NULL) {
365
str->bufferSize = str->maxlrec;
366
str->buffer = (char *) malloc(sizeof(char) * (str->maxlrec + 1));
370
xdrmem_create(str->xdr, str->buffer, str->maxlrec, XDR_ENCODE);
371
str->firstPos = xdr_getpos(str->xdr);
372
str->status = MCFIO_BOF;
374
if (str->fhead == NULL) {
375
str->fhead = (mcfxdrFileHeader *) malloc(sizeof(mcfxdrFileHeader));
376
str->fhead->blockIds = NULL;
377
str->fhead->blockNames = NULL;
380
** Fill the file header, additional info will be written on tape
382
if (title == NULL) strcpy(str->fhead->title,"No Title given");
383
else strcpy(str->fhead->title,title);
385
if (comment == NULL) strcpy(str->fhead->comment,"No comment");
386
else strcpy(str->fhead->comment, comment);
387
str->fhead->numevts_expect = numevts_pred;
388
str->fhead->numevts = 0;
389
str->fhead->dimTable = 0;
390
str->fhead->firstTable = 0;
391
str->fhead->nBlocks = nBlocks;
392
str->fhead->nNTuples = 0;
393
if (str->fhead->blockIds != NULL) free(str->fhead->blockIds);
394
str->fhead->blockIds = (int *) malloc(sizeof(int) * nBlocks);
395
if (str->fhead->blockNames != NULL) {
396
for (i=0; i<nBlocks; i++) if (str->fhead->blockNames[i] != NULL) {
397
free(str->fhead->blockNames[i]);
398
str->fhead->blockNames[i] = NULL;
400
free(str->fhead->blockNames);
402
str->fhead->blockNames = (char**) malloc(sizeof(char*) * nBlocks);
403
for (i=0; i<nBlocks; i++) {
404
str->fhead->blockIds[i] = blkIds[i];
405
str->fhead->blockNames[i] =
406
(char *) malloc(sizeof(char) * (MCF_XDR_B_TITLE_LENGTH + 1));
407
mcfioC_GetBlockName(blkIds[i], str->fhead->blockNames[i]);
410
p1 = xdr_getpos(str->xdr);
412
if (xdr_mcfast_fileheader(str->xdr, &idtmp,
413
&ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
415
"mcfio_OpenWriteSequential: Unable to encode fileheader \n");
416
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
417
rbfclose_(&jfn, &iost);
421
** write this buffer.
423
str->numWordsC += (ntot/4);
424
p2 = xdr_getpos(str->xdr);
426
if (ldat < 512) ldat = 512;
427
rbwrite_(&jfn, str->buffer, &ldat, &lwdat, &iost);
430
" mcfio_OpenWriteSequential: Problem writing first record on \n device %s, \
431
VSN %s, file %d \n", device, vsn, filenumber);
432
fprintf(stderr, " Status from Rbio %d \n", iost);
433
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
434
rbfclose_(&jfn, &iost);
437
str->numWordsT += (lwdat/4);
438
/* printf(" Wrote in Open Seq. %d \n" , lwdat); */
439
xdr_setpos(str->xdr, str->firstPos);
440
str->currentPos = str->firstPos ;
441
str->status = MCFIO_RUNNING;
443
** Compose the dummy Sequential header to the first buffer.
445
if (str->shead == NULL)
446
str->shead = (mcfxdrSequentialHeader *)
447
malloc(sizeof(mcfxdrSequentialHeader));
448
str->shead->nRecords = 1;
449
idtmp = SEQUENTIALHEADER;
450
if (xdr_mcfast_seqheader(str->xdr, &idtmp,
451
&ntot, McfGenericVersion, &(str->shead)) == FALSE) {
453
"mcfio_OpenWriteSequential: Unable to encode fileheader \n");
454
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
455
rbfclose_(&jfn, &iost);
460
** Compose the first dummy event header into memory. This will overwritten
461
** with the complete information upon closure of the event.
463
str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
464
str->ehead->dimBlocks = str->fhead->nBlocks;
465
str->ehead->nBlocks = 0;
466
str->ehead->nNTuples = 0;
467
str->ehead->dimNTuples = str->fhead->nNTuples;
468
str->ehead->evtnum = 0;
469
str->ehead->previousevtnum = 0;
470
str->ehead->storenum = 0;
471
str->ehead->runnum = 0;
472
str->ehead->trigMask = 0;
473
str->ehead->blockIds = (int *) malloc(sizeof(int) * str->fhead->nBlocks);
474
str->ehead->ptrBlocks = (u_int *) malloc(sizeof(int) * str->fhead->nBlocks);
475
str->ehead->nTupleIds = (int *) malloc(sizeof(int) * str->fhead->nNtuples);
476
str->ehead->ptrNTuples =
477
(u_int *) malloc(sizeof(int) * str->fhead->nNtuples);
478
if (mcfioC_WrtEvt(str, INITIATE) == FALSE) {
480
"mcfio_OpenWriteSequential: Unable to encode Evtheader \n");
481
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
482
rbfclose_(&jfn, &iost);
485
str->ehead->evtnum = 0;
486
McfNumOfStreamActive++;
491
int mcfioC_NextEventSequential(int stream)
493
int i, j, jstr, idtmp, ntot, ok, jfn, lrdat, lwdat, ldat, iost, lrem;
500
str = McfStreamPtrList[jstr];
503
** Branching code Here, INPUT vs OUTPUT
505
if (str->row == MCFIO_READ) {
507
** Read the first record. Decode the Sequential header. Read more records
510
if (str->buffer2 == NULL)
511
str->buffer2 = (char *) malloc(sizeof(char)* (str->maxlrec+1));
512
rbread_(&jfn, str->buffer2, &(str->maxlrec), &lrdat, &iost);
515
" mcfio_NextEventSequential: \n\
516
Problem reading first record for this evt, stream %d, Rbio status %d \n",
518
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
519
rbfclose_(&jfn, &iost);
523
** Read the Sequential header to get the number of buffers.
525
if (str->shead == NULL)
527
(mcfxdrSequentialHeader *) malloc(sizeof(mcfxdrSequentialHeader));
528
xdrmem_create(str->xdr, str->buffer2, str->maxlrec, XDR_DECODE);
529
str->firstPos = xdr_getpos(str->xdr);
530
if (xdr_mcfast_seqheader(str->xdr, &idtmp,
531
&ntot, McfGenericVersion, &(str->shead)) == FALSE) {
533
"mcfio_NextEventSequential: Unable to decode seqheader \n");
534
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
535
rbfclose_(&jfn, &iost);
538
str->currentPos = xdr_getpos(str->xdr);
539
str->numWordsC += (ntot/4);
540
if (str->shead->nRecords > 1) {
541
if (str->bufferSize < (str->shead->nRecords * str->maxlrec)) {
542
if (str->buffer != NULL) free(str->buffer);
543
str->bufferSize = (str->shead->nRecords * str->maxlrec);
544
str->buffer = (char *) malloc(sizeof(char) * (str->bufferSize+1));
546
tmpbuf = str->buffer;
547
memcpy(str->buffer, str->buffer2,lrdat);
549
for (i=1; i<str->shead->nRecords; i++) {
550
rbread_(&jfn, tmpbuf, &(str->maxlrec), &lrdat, &iost);
553
" mcfio_NextEventSequential: \n\
554
Problem reading first record for this evt, stream %d, Rbio status\n",
556
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
557
rbfclose_(&jfn, &iost);
563
** We have to reposition ourselves..
565
xdrmem_create(str->xdr, str->buffer, str->bufferSize, XDR_DECODE);
566
xdr_setpos(str->xdr, str->currentPos);
568
if (xdr_mcfast_eventheader(str->xdr, &idtmp,
569
&ntot, McfGenericVersion, &(str->ehead)) == FALSE) {
571
"mcfio_NextEventSequential: Unable to decode evtheader \n");
572
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
573
rbfclose_(&jfn, &iost);
576
str->currentPos = xdr_getpos(str->xdr);
577
str->numWordsC += (ntot/4);
578
} else { /* Writing an event.. */
580
** The entire buffer is at str->buffer. it has a size of
581
** str->bufferSize bytes. First, we have to compute the number of
582
** records, rewrite the Sequential header, and the Event header.
584
p1 = str->currentPos;
585
str->shead->nRecords = 1 + (p1 - str->firstPos)/str->maxlrec;
586
if (((p1 - str->firstPos) % str->maxlrec) == 0) str->shead->nRecords--;
587
xdr_setpos(str->xdr, str->firstPos);
588
idtmp = SEQUENTIALHEADER;
589
xdr_mcfast_seqheader(str->xdr, &idtmp,
590
&ntot, McfGenericVersion, &(str->shead));
591
str->numWordsC += (ntot/4);
592
str->currentPos = xdr_getpos(str->xdr);
593
str->ehead->evtnum++;
595
xdr_mcfast_eventheader(str->xdr, &idtmp,
596
&ntot, McfGenericVersion, &(str->ehead));
597
str->currentPos = xdr_getpos(str->xdr);
598
str->numWordsC += (ntot/4);
600
** The buffer is ready to be written to sequential media
604
lrem = p1 - str->firstPos;
605
for (i=0, tmpbuf=str->buffer; i<str->shead->nRecords; i++) {
606
if (i == (str->shead->nRecords - 1))
607
ldat = (lrem > 512) ? lrem : 512;
610
rbwrite_(&jfn, tmpbuf, &ldat, &lwdat, &iost);
611
/* printf(" Wrote in evt loop %d \n" , lwdat); */
614
" mcfio_NextEventSequential: \n\
615
Problem writing record on Stream %d, Rbio status %d ", stream, iost);
616
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
617
rbfclose_(&jfn, &iost);
620
str->numWordsT += lwdat/4;
625
** Initiate a new bufffer
627
str->shead->nRecords = 1;
628
xdr_setpos(str->xdr, str->firstPos);
629
idtmp = SEQUENTIALHEADER;
630
if (xdr_mcfast_seqheader(str->xdr, &idtmp,
631
&ntot, McfGenericVersion, &(str->shead)) == FALSE) {
633
"mcfio_OpenWriteSequential: Unable to encode fileheader \n");
634
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
635
rbfclose_(&jfn, &iost);
638
str->currentPos = xdr_getpos(str->xdr);
639
str->ehead->nBlocks = 0;
640
str->ehead->previousevtnum = str->ehead->evtnum;
641
if (mcfioC_WrtEvt(str, INITIATE) == FALSE) {
643
"mcfio_OpenWriteSequential: Unable to encode Evtheader \n");
644
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
645
rbfclose_(&jfn, &iost);
648
str->ehead->evtnum = str->ehead->previousevtnum;
651
str->status = MCFIO_RUNNING;
652
return MCFIO_RUNNING;
655
void mcfioC_CloseSequentialFile(int stream)
661
str = McfStreamPtrList[jstr];
662
str->status = MCFIO_EOF;
664
rbclose_(&jfn, &iost);
667
" mcfio_CloseSequentialFile: \n\
668
Problem closing file Stream %d, Rbio status %d ", jstr, iost);
669
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
673
void mcfioC_CloseSequentialTape(int stream)
679
str = McfStreamPtrList[jstr];
681
rbfclose_(&jfn, &iost);
683
** This suppose to work,
686
if (strcmp(str->vsn,"Disk") != 0) rbrewind_(&jfn, &iost);
687
rbumount_(&jfn, &iost);
691
" mcfio_CloseSequentialTape: \n\
692
Problem closing file Stream %d, Rbio status %d ", stream, iost);
693
mcfioC_FreeStream(&McfStreamPtrList[jstr]);