/************************************************/ /* */ /* File : dmap.c */ /* Description : detector map library */ /* */ /* Author: Sfiligoi Igor */ /* */ /* Created : 07.04.1997 */ /* Last modified: 18.08.1997 */ /* */ /************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <Error.h> #include <GeoVme.h> #include "dmap.h" #include "dmap_write.h" /* Empty definitions */ #define DMAP_DET_VOID 0 /* not present */ #define DMAP_BTYPE_VOID 0 /* not present */ /* Calorimeter ADC and TDC */ #define DMAP_CAL_CHANS_PER_BOARD 30 /* Chamber TDC */ #define DMAP_CHAMBER_CHANS_PER_BOARD 96 #define DMAP_WIRE_VOID 0xffff /* not present */ /* QCAL ADC and TDC */ #define DMAP_QCAL_CHANS_PER_BOARD 30 /* Board */ typedef union { DMAP_CAL_EL *cal; /* array */ DMAP_CHAMBER_EL *chamber; /* array */ DMAP_QCAL_EL *qcal; /* array */ } DMAP_BOARD_SUB_EL; typedef struct { unsigned char btype; /* See DMAP_BTYPE_.. constants */ DMAP_BOARD_SUB_EL data; } DMAP_BOARD_EL; /* Crate */ #define DMAP_BOARDS_PER_CRATE 16 typedef DMAP_BOARD_EL DMAP_CRATE_EL[DMAP_BOARDS_PER_CRATE]; /* Chain */ typedef struct { int nrcrates; /* nr of crates in the chain, >=1 */ DMAP_CRATE_EL *crate; /* array, element 0 is the crate 1 */ } DMAP_CHAIN_EL; /**************************************************************************/ /* System */ #define DMAP_NR_CHAINS GEOVME_MAX_NUM_CHAINS DMAP_CHAIN_EL dmap[DMAP_NR_CHAINS]; /* element 0 is the chain 1 */ char dmap_initialized = 0; /**************************************************************************/ /******************************************/ /* Initialization functions */ /******************************************/ /* allocate the necessary structures */ /* use the GeoVme */ int dmap_init(void) { int chain_nr; if (dmap_initialized==1) { /* non fatal error */ fprintf(stderr,"WARNING in dmap_init: Dmap already initialized.\n"); } for (chain_nr=1; chain_nr<=DMAP_NR_CHAINS; chain_nr++) { int chain_idx = chain_nr-1; int nrcrates; int crate_nr; /* find out the number of crates */ for (nrcrates=1; GeoVme_btype(chain_nr,nrcrates,21)==GEOVME_ROCK_BTYPE; /* include only crates with a rock */ nrcrates++); dmap[chain_idx].nrcrates = nrcrates; if (nrcrates>1) { dmap[chain_idx].crate = (DMAP_CRATE_EL *) malloc((nrcrates-1)*sizeof(DMAP_CRATE_EL)); if (dmap[chain_idx].crate==NULL) { ErrorSetF(DMAP_ERROR_UNKNOWN,"dmap_init","Malloc returned NULL."); return DMAP_ERROR_UNKNOWN; } } else dmap[chain_idx].crate=NULL; for (crate_nr=1; crate_nr<nrcrates; crate_nr++) { int crate_idx = crate_nr-1; int board_nr; for (board_nr=0; board_nr<DMAP_BOARDS_PER_CRATE; board_nr++) { int btype; /* find out it the board is present and its type */ btype = GeoVme_btype(chain_nr,crate_nr,board_nr+5); switch (btype) { case GEOVME_CADC_BTYPE: case GEOVME_CTDC_BTYPE: { int chan_nr; if (btype==GEOVME_CADC_BTYPE) dmap[chain_idx].crate[crate_idx][board_nr].btype = DMAP_BTYPE_CALADC; else dmap[chain_idx].crate[crate_idx][board_nr].btype = DMAP_BTYPE_CALTDC; dmap[chain_idx].crate[crate_idx][board_nr].data.cal = (DMAP_CAL_EL *) malloc(DMAP_CAL_CHANS_PER_BOARD*sizeof(DMAP_CAL_EL)); if (dmap[chain_idx].crate[crate_idx][board_nr].data.cal==NULL) { ErrorSetF(DMAP_ERROR_UNKNOWN,"dmap_init","Malloc returned NULL."); return DMAP_ERROR_UNKNOWN; } for (chan_nr=0; chan_nr<DMAP_CAL_CHANS_PER_BOARD; chan_nr++) { dmap[chain_idx].crate[crate_idx][board_nr].data.cal[chan_nr].detector = DMAP_DET_VOID; /* other fields are undefined */ } } break; #define GEOVME_CHAMBER_BTYPE 2 case GEOVME_CHAMBER_BTYPE: { int chan_nr; dmap[chain_idx].crate[crate_idx][board_nr].btype = DMAP_BTYPE_CHATDC; dmap[chain_idx].crate[crate_idx][board_nr].data.chamber = (DMAP_CHAMBER_EL *) malloc(DMAP_CHAMBER_CHANS_PER_BOARD*sizeof(DMAP_CHAMBER_EL)); if (dmap[chain_idx].crate[crate_idx][board_nr].data.chamber==NULL) { ErrorSetF(DMAP_ERROR_UNKNOWN,"dmap_init","Malloc returned NULL."); return DMAP_ERROR_UNKNOWN; } for (chan_nr=0; chan_nr<DMAP_CHAMBER_CHANS_PER_BOARD; chan_nr++) { dmap[chain_idx].crate[crate_idx][board_nr].data.chamber[chan_nr].wire = DMAP_WIRE_VOID; /* other fields are undefined */ } } break; #define GEOVME_QADC_BTYPE 3 #define GEOVME_QTDC_BTYPE 4 case GEOVME_QADC_BTYPE: case GEOVME_QTDC_BTYPE: { int chan_nr; if (btype==GEOVME_QADC_BTYPE) dmap[chain_idx].crate[crate_idx][board_nr].btype = DMAP_BTYPE_QCALADC; else dmap[chain_idx].crate[crate_idx][board_nr].btype = DMAP_BTYPE_QCALTDC; dmap[chain_idx].crate[crate_idx][board_nr].data.qcal = (DMAP_QCAL_EL *) malloc(DMAP_QCAL_CHANS_PER_BOARD*sizeof(DMAP_QCAL_EL)); if (dmap[chain_idx].crate[crate_idx][board_nr].data.qcal==NULL) { ErrorSetF(DMAP_ERROR_UNKNOWN,"dmap_init","Malloc returned NULL."); return DMAP_ERROR_UNKNOWN; } for (chan_nr=0; chan_nr<DMAP_QCAL_CHANS_PER_BOARD; chan_nr++) { dmap[chain_idx].crate[crate_idx][board_nr].data.qcal[chan_nr].detector = DMAP_DET_VOID; /* other fields are undefined */ } } break; default: { if (btype==GEOVME_ROCK_BTYPE) { /* Nonfatal error */ fprintf(stderr,"WARNING in dmap_init: GeoVme reported a ROCK in %i %i %i!\n",chain_nr, crate_nr, board_nr); } dmap[chain_idx].crate[crate_idx][board_nr].btype = DMAP_BTYPE_VOID; } break; } } } } dmap_initialized = 1; return DMAP_ERROR_OK; } /* return 0 if it is not a comment, 1 else */ int dmap_load_iscomment(char *buffer) { int i; for (i=0; buffer[i]==' ' ;i++); if ((buffer[i]==0)|| /* blank line */ (buffer[i]=='%')) /* comment */ return 1; else return 0; } /* load the map in memory */ int dmap_load(char *filename) { FILE *fmap; int res; char buffer[1024]; int line_nr; res = dmap_init(); if (res!=DMAP_ERROR_OK) { ErrorSetF(res,"dmap_load","dmap_init error: %s",ErrorGetMessage()); return res; } fmap = fopen(filename,"r"); if (fmap==NULL) { ErrorSetF(DMAP_ERROR_UNKNOWN,"dma_load","Error opening file %s.",filename); return DMAP_ERROR_UNKNOWN; } line_nr = 0; while (fscanf(fmap,"%[^\n]\n",buffer)!=EOF) { int chain_nr,crate_nr,board_nr,chan_nr,detector; char ibuffer[1024]; char detector_str[128]; line_nr++; if (dmap_load_iscomment(buffer)) continue; /* skip comments */ if (sscanf(buffer,"%i %i %i %i %[^ ] %[^\n]",&chain_nr,&crate_nr,&board_nr,&chan_nr,detector_str,ibuffer)!=6) { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Error in the first half of line %i.",line_nr); return DMAP_ERROR_LOAD_LINE; } if (strcmp(detector_str,"ECAPA")==0) detector = DMAP_DET_ECAPA; else if (strcmp(detector_str,"ECAPB")==0) detector = DMAP_DET_ECAPB; else if (strcmp(detector_str,"BARR")==0) detector = DMAP_DET_BARREL; else if (strcmp(detector_str,"CHAMB")==0) detector = DMAP_DET_CHAMBER; else if (strcmp(detector_str,"QCALA")==0) detector = DMAP_DET_QCALA; else if (strcmp(detector_str,"QCALB")==0) detector = DMAP_DET_QCALB; else { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Invalid detector in line %i. (Should be ECAPA, BARR, ECAPB, CHAMB, QCALA or QCALB)",line_nr); return DMAP_ERROR_LOAD_LINE; } if ((chain_nr<1)||(chain_nr>DMAP_NR_CHAINS)) { fclose(fmap); ErrorSetF(DMAP_ERROR_CHECK_LINE,"dmap_load","Chain nr out of range in line %i. (%i)",line_nr,chain_nr); return DMAP_ERROR_CHECK_LINE; } if ((crate_nr<1)||(crate_nr>=dmap[chain_nr-1].nrcrates)) { fclose(fmap); ErrorSetF(DMAP_ERROR_CHECK_LINE,"dmap_load","Crate nr out of range in line %i. (%i)",line_nr,crate_nr); return DMAP_ERROR_CHECK_LINE; } if ((board_nr<0)||(board_nr>=DMAP_BOARDS_PER_CRATE)) { fclose(fmap); ErrorSetF(DMAP_ERROR_CHECK_LINE,"dmap_load","Board nr out of range in line %i. (%i)",line_nr,board_nr); return DMAP_ERROR_CHECK_LINE; } if (detector==DMAP_DET_CHAMBER) { int layer,wire; if ((chan_nr<0)||(chan_nr>=DMAP_CHAMBER_CHANS_PER_BOARD)) { fclose(fmap); ErrorSetF(DMAP_ERROR_CHECK_LINE,"dmap_load","Chan nr out of range in line %i. (%i)",line_nr,chan_nr); return DMAP_ERROR_CHECK_LINE; } if (dmap[chain_nr-1].crate[crate_nr-1][board_nr].btype!=DMAP_BTYPE_CHATDC) { fclose(fmap); ErrorSetF(DMAP_ERROR_CONSISTENCY,"dmap_load","Board type invalid in line %i. (GeoVme %i, Read %i)", line_nr, dmap[chain_nr-1].crate[crate_nr-1][board_nr].btype, DMAP_BTYPE_CHATDC); return DMAP_ERROR_CONSISTENCY; } if (sscanf(ibuffer,"%i %i",&layer,&wire)!=2) { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Error in the second half of line %i (chamber).",line_nr); return DMAP_ERROR_LOAD_LINE; } { DMAP_CHAMBER_EL *el; el = &(dmap[chain_nr-1].crate[crate_nr-1][board_nr].data.chamber[chan_nr]); if (el->wire!=DMAP_WIRE_VOID) { /* was already set before */ fclose(fmap); ErrorSetF(DMAP_ERROR_REPEAT,"dmap_load","Repeated set in line %i.",line_nr); return DMAP_ERROR_REPEAT; } /* no errors, set the element*/ el->layer = layer; el->wire = wire; } } /* end chamber */ else if ((detector==DMAP_DET_ECAPA)|| (detector==DMAP_DET_ECAPB)|| (detector==DMAP_DET_BARREL)) { int module,plane,column,side,card; char card_str[128]; if ((chan_nr<0)||(chan_nr>=DMAP_CAL_CHANS_PER_BOARD)) { fclose(fmap); ErrorSetF(DMAP_ERROR_CHECK_LINE,"dmap_load","Chan nr out of range in line %i. (%i)",line_nr,chan_nr); return DMAP_ERROR_CHECK_LINE; } if (sscanf(ibuffer,"%i %i %i %i %s",&module,&plane,&column,&side,card_str)!=5) { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Error in the second half of line %i (calorimeter).",line_nr); return DMAP_ERROR_LOAD_LINE; } if (strcmp(card_str,"CALADC")==0) card = DMAP_BTYPE_CALADC; else if (strcmp(card_str,"CALTDC")==0) card = DMAP_BTYPE_CALTDC; else { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Invalid calorimter card in line %i. (Should be CALADC or CALTDC)",line_nr); return DMAP_ERROR_LOAD_LINE; } if (dmap[chain_nr-1].crate[crate_nr-1][board_nr].btype!=card) { fclose(fmap); ErrorSetF(DMAP_ERROR_CONSISTENCY,"dmap_load","Board type invalid in line %i. (GeoVme %i, Read %i)", line_nr, dmap[chain_nr-1].crate[crate_nr-1][board_nr].btype, card); return DMAP_ERROR_CONSISTENCY; } { DMAP_CAL_EL *el; el = &(dmap[chain_nr-1].crate[crate_nr-1][board_nr].data.cal[chan_nr]); if (el->detector!=DMAP_DET_VOID) { /* was already set before */ fclose(fmap); ErrorSetF(DMAP_ERROR_REPEAT,"dmap_load","Repeated set in line %i.",line_nr); return DMAP_ERROR_REPEAT; } /* no errors, set the element */ el->detector = detector; el->module = module; el->plane = plane; el->column = column; el->side = side; } } /* end cal */ else if ((detector==DMAP_DET_QCALA)|| (detector==DMAP_DET_QCALB)) { int module,card; char card_str[128]; if ((chan_nr<0)||(chan_nr>=DMAP_QCAL_CHANS_PER_BOARD)) { fclose(fmap); ErrorSetF(DMAP_ERROR_CHECK_LINE,"dmap_load","Chan nr out of range in line %i. (%i)",line_nr,chan_nr); return DMAP_ERROR_CHECK_LINE; } if (sscanf(ibuffer,"%i %s",&module,card_str)!=3) { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Error in the second half of line %i (QCAL).",line_nr); return DMAP_ERROR_LOAD_LINE; } if (strcmp(card_str,"QCALADC")==0) card = DMAP_BTYPE_QCALADC; else if (strcmp(card_str,"QCALTDC")==0) card = DMAP_BTYPE_QCALTDC; else { fclose(fmap); ErrorSetF(DMAP_ERROR_LOAD_LINE,"dmap_load","Invalid calorimter card in line %i. (Should be QCALADC or QCALTDC)",line_nr); return DMAP_ERROR_LOAD_LINE; } if (dmap[chain_nr-1].crate[crate_nr-1][board_nr].btype!=card) { fclose(fmap); ErrorSetF(DMAP_ERROR_CONSISTENCY,"dmap_load","Board type invalid in line %i. (GeoVme %i, Read %i)", line_nr, dmap[chain_nr-1].crate[crate_nr-1][board_nr].btype, card); return DMAP_ERROR_CONSISTENCY; } { DMAP_QCAL_EL *el; el = &(dmap[chain_nr-1].crate[crate_nr-1][board_nr].data.qcal[chan_nr]); if (el->detector!=DMAP_DET_VOID) { /* was already set before */ fclose(fmap); ErrorSetF(DMAP_ERROR_REPEAT,"dmap_load","Repeated set in line %i.",line_nr); return DMAP_ERROR_REPEAT; } /* no errors, set the element */ el->detector = detector; el->module = module; } } /* end qcal */ } fclose(fmap); return DMAP_ERROR_OK; } /* free the allocated memory */ int dmap_dispose() { int chain_nr; if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_dispose","Dmap not initialized!"); return DMAP_ERROR_NOTINIT; } for (chain_nr=1; chain_nr<=DMAP_NR_CHAINS; chain_nr++) { int chain_idx = chain_nr-1; int crate_nr; for (crate_nr=1; crate_nr<dmap[chain_idx].nrcrates; crate_nr++) { int crate_idx = crate_nr-1; int board_nr; for (board_nr=0; board_nr<DMAP_BOARDS_PER_CRATE; board_nr++) { int btype = dmap[chain_idx].crate[crate_idx][board_nr].btype; if (btype != DMAP_BTYPE_VOID) { /* if void, nothing to do */ if (btype == DMAP_BTYPE_CHATDC) free(dmap[chain_idx].crate[crate_idx][board_nr].data.chamber); else if ((btype==DMAP_BTYPE_CALADC)||(btype==DMAP_BTYPE_CALTDC)) free(dmap[chain_idx].crate[crate_idx][board_nr].data.cal); else free(dmap[chain_idx].crate[crate_idx][board_nr].data.qcal); } } } free(dmap[chain_idx].crate); } dmap_initialized = 0; return DMAP_ERROR_OK; } /******************************************/ /* Decode functions */ /******************************************/ int dmap_get(unsigned char chain, /* IN: chain */ unsigned char crate, /* IN: crate */ unsigned char slot, /* IN: slot */ unsigned char chan, /* IN: channel */ DMAP_CHAN_EL *data) /* OUT: associated data */ { int btype; if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_get","Dmap not initialized!"); return DMAP_ERROR_NOTINIT; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_get","Chain nr out of range. (%i)",chain); return DMAP_ERROR_RANGE; } if ((crate<1)||(crate>=dmap[chain-1].nrcrates)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_get","Crate nr out of range. (%i)",crate); return DMAP_ERROR_RANGE; } if (slot>=DMAP_BOARDS_PER_CRATE) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_get","Slot nr out of range. (%i)",slot); return DMAP_ERROR_RANGE; } btype = dmap[chain-1].crate[crate-1][slot].btype; data->btype = btype; switch (btype) { case DMAP_BTYPE_CALTDC: case DMAP_BTYPE_CALADC: if (chan>=DMAP_CAL_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_get","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } data->data.cal = dmap[chain-1].crate[crate-1][slot].data.cal[chan]; if (data->data.cal.detector==DMAP_DET_VOID) { ErrorClear(); return DMAP_ERROR_EMPTY; /* not a real error */ } break; case DMAP_BTYPE_CHATDC: if (chan>=DMAP_CHAMBER_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } data->data.chamber = dmap[chain-1].crate[crate-1][slot].data.chamber[chan]; if (data->data.chamber.wire==DMAP_WIRE_VOID) { ErrorClear(); return DMAP_ERROR_EMPTY; /* not a real error */ } break; case DMAP_BTYPE_QCALTDC: case DMAP_BTYPE_QCALADC: if (chan>=DMAP_QCAL_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } data->data.qcal = dmap[chain-1].crate[crate-1][slot].data.qcal[chan]; if (data->data.qcal.detector==DMAP_DET_VOID) { ErrorClear(); return DMAP_ERROR_EMPTY; /* not a real error */ } break; default: { ErrorClear(); return DMAP_ERROR_EMPTY; /* not a real error */ } break; } return DMAP_ERROR_OK; } /******************************************/ /* Encode functions */ /******************************************/ int dmap_find(DMAP_CHAN_EL data, /* IN: data to find */ unsigned char *chain, /* OUT: chain */ unsigned char *crate, /* OUT: crate */ unsigned char *slot, /* OUT: slot */ unsigned char *chan) /* OUT: channel */ { if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_find","Dmap not initialized!"); return DMAP_ERROR_NOTINIT; } if ((data.btype<1)||(data.btype>5)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_find","Invalid board type. (%i)",data.btype); return DMAP_ERROR_RANGE; } switch (data.btype) { case DMAP_BTYPE_CALTDC: case DMAP_BTYPE_CALADC: if ((data.data.cal.detector!=DMAP_DET_ECAPA)&& (data.data.cal.detector!=DMAP_DET_BARREL)&& (data.data.cal.detector!=DMAP_DET_ECAPB)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_find","Invalid detecor type. (cal %i)",data.data.cal.detector); return DMAP_ERROR_RANGE; } break; case DMAP_BTYPE_CHATDC: if (data.data.chamber.wire==DMAP_WIRE_VOID) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_find","Invalid wire nr. (chamber)"); return DMAP_ERROR_RANGE; } break; case DMAP_BTYPE_QCALTDC: case DMAP_BTYPE_QCALADC: if ((data.data.qcal.detector!=DMAP_DET_QCALA)&& (data.data.qcal.detector!=DMAP_DET_QCALB)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_find","Invalid detecor type. (qcal %i)",data.data.qcal.detector); return DMAP_ERROR_RANGE; } break; } { int chain_nr; for (chain_nr=1; chain_nr<=DMAP_NR_CHAINS; chain_nr++) { int crate_nr; int chain_idx = chain_nr-1; for (crate_nr=1; crate_nr<dmap[chain_idx].nrcrates; crate_nr++) { int board_nr; int crate_idx = crate_nr-1; for (board_nr=0; board_nr<DMAP_BOARDS_PER_CRATE; board_nr++) { if (dmap[chain_idx].crate[crate_idx][board_nr].btype==data.btype) switch (data.btype) { case DMAP_BTYPE_CALTDC: case DMAP_BTYPE_CALADC: { int chan_nr; for (chan_nr=0; chan_nr<DMAP_CAL_CHANS_PER_BOARD; chan_nr++) { DMAP_CAL_EL *el; el = &(dmap[chain_idx].crate[crate_idx][board_nr].data.cal[chan_nr]); if ((el->detector==data.data.cal.detector)&& (el->module==data.data.cal.module)&& (el->plane==data.data.cal.plane)&& (el->column==data.data.cal.column)&& (el->side==data.data.cal.side)) { /* found */ *chain = chain_nr; *crate = crate_nr; *slot = board_nr; *chan = chan_nr; return DMAP_ERROR_OK; } } } break; case DMAP_BTYPE_CHATDC: { int chan_nr; for (chan_nr=0; chan_nr<DMAP_CHAMBER_CHANS_PER_BOARD; chan_nr++) { DMAP_CHAMBER_EL *el; el = &(dmap[chain_idx].crate[crate_idx][board_nr].data.chamber[chan_nr]); if ((el->layer==data.data.chamber.layer)&& (el->wire==data.data.chamber.wire)) { /* found */ *chain = chain_nr; *crate = crate_nr; *slot = board_nr; *chan = chan_nr; return DMAP_ERROR_OK; } } } break; case DMAP_BTYPE_QCALTDC: case DMAP_BTYPE_QCALADC: { int chan_nr; for (chan_nr=0; chan_nr<DMAP_QCAL_CHANS_PER_BOARD; chan_nr++) { DMAP_QCAL_EL *el; el = &(dmap[chain_idx].crate[crate_idx][board_nr].data.qcal[chan_nr]); if ((el->detector==data.data.qcal.detector)&& (el->module==data.data.qcal.module)) { /* found */ *chain = chain_nr; *crate = crate_nr; *slot = board_nr; *chan = chan_nr; return DMAP_ERROR_OK; } } } break; } } } } } ErrorClear(); return DMAP_ERROR_EMPTY; } /******************************************/ /* Query functions */ /******************************************/ /* returns the number of chains, or DMAP_ERROR_UNKNOWN in case of error */ int dmap_query_nr_chains(void) { if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_query_nr_chains","Dmap not initialized!"); return DMAP_ERROR_UNKNOWN; } return DMAP_NR_CHAINS; } /* returns the number of crates in the chain, or DMAP_ERROR_UNKNOWN in case of error */ int dmap_query_nr_crates(unsigned char chain) { if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_query_nr_crates","Dmap not initialized!"); return DMAP_ERROR_UNKNOWN; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_nr_crates","Chain nr out of range. (%i)",chain); return DMAP_ERROR_UNKNOWN; } return dmap[chain-1].nrcrates; } /* returns the number of slots in the crate, or DMAP_ERROR_UNKNOWN in case of error */ int dmap_query_nr_slots(unsigned char chain, unsigned char crate) { if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_query_nr_slots","Dmap not initialized!"); return DMAP_ERROR_UNKNOWN; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_nr_slots","Chain nr out of range. (%i)",chain); return DMAP_ERROR_UNKNOWN; } if ((crate<1)||(crate>=dmap[chain-1].nrcrates)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_nr_slots","Crate nr out of range. (%i)",crate); return DMAP_ERROR_UNKNOWN; } return DMAP_BOARDS_PER_CRATE; } /* returns the number of channels in the slot, 0 if the board is empty, or DMAP_ERROR_UNKNOWN in case of error */ int dmap_query_nr_chans(unsigned char chain, unsigned char crate, unsigned char slot) { int btype; if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_query_nr_chans","Dmap not initialized!"); return DMAP_ERROR_UNKNOWN; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_nr_chans","Chain nr out of range. (%i)",chain); return DMAP_ERROR_UNKNOWN; } if ((crate<1)||(crate>=dmap[chain-1].nrcrates)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_nr_chans","Crate nr out of range. (%i)",crate); return DMAP_ERROR_UNKNOWN; } if (slot>=DMAP_BOARDS_PER_CRATE) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_nr_chans","Slot nr out of range. (%i)",slot); return DMAP_ERROR_UNKNOWN; } btype = dmap[chain-1].crate[crate-1][slot].btype; switch (btype) { case DMAP_BTYPE_CALADC: case DMAP_BTYPE_CALTDC: return DMAP_CAL_CHANS_PER_BOARD; case DMAP_BTYPE_CHATDC: return DMAP_CHAMBER_CHANS_PER_BOARD; case DMAP_BTYPE_QCALADC: case DMAP_BTYPE_QCALTDC: return DMAP_QCAL_CHANS_PER_BOARD; default: return 0; } } /* returns the type of the board in the slot, DMAP_ERROR_EMPTY if the board is empty, or DMAP_ERROR_UNKNOWN in case of error */ int dmap_query_btype(unsigned char chain, unsigned char crate, unsigned char slot) { int btype; if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_query_btype","Dmap not initialized!"); return DMAP_ERROR_UNKNOWN; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_btype","Chain nr out of range. (%i)",chain); return DMAP_ERROR_UNKNOWN; } if ((crate<1)||(crate>=dmap[chain-1].nrcrates)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_btype","Crate nr out of range. (%i)",crate); return DMAP_ERROR_UNKNOWN; } if (slot>=DMAP_BOARDS_PER_CRATE) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_query_btype","Slot nr out of range. (%i)",slot); return DMAP_ERROR_UNKNOWN; } btype = dmap[chain-1].crate[crate-1][slot].btype; if (btype==DMAP_BTYPE_VOID) return DMAP_ERROR_EMPTY; else return btype; } /****************************************************************/ /* dmap_write */ /****************************************************************/ /******************************************/ /* Initialization functions */ /******************************************/ /* creates a new empty map in memory (based on GeoVme) */ /* Is alternative to dmap_load */ int dmap_new(void) { int res; res = dmap_init(); if (res!=DMAP_ERROR_OK) { ErrorSetF(res,"dmap_new","dmap_init error: %s",ErrorGetMessage()); return res; } return DMAP_ERROR_OK; } /******************************************/ /* Set function */ /******************************************/ int dmap_set(unsigned char chain, /* IN: chain */ unsigned char crate, /* IN: crate */ unsigned char slot, /* IN: slot */ unsigned char chan, /* IN: channel */ DMAP_CHAN_EL data) /* IN: new data */ { int btype; if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_set","Dmap not initialized!"); return DMAP_ERROR_NOTINIT; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Chain nr out of range. (%i)",chain); return DMAP_ERROR_RANGE; } if ((crate<1)||(crate>=dmap[chain-1].nrcrates)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Crate nr out of range. (%i)",crate); return DMAP_ERROR_RANGE; } if (slot>=DMAP_BOARDS_PER_CRATE) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Slot nr out of range. (%i)",slot); return DMAP_ERROR_RANGE; } btype = dmap[chain-1].crate[crate-1][slot].btype; if (btype!=data.btype) { ErrorSetF(DMAP_ERROR_CONSISTENCY,"dmap_set","Invalid btype. (Was %i New %i)",btype,data.btype); return DMAP_ERROR_CONSISTENCY; } switch (btype) { case DMAP_BTYPE_CALTDC: case DMAP_BTYPE_CALADC: if (chan>=DMAP_CAL_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } if ((data.data.cal.detector!=DMAP_DET_ECAPA)&& (data.data.cal.detector!=DMAP_DET_ECAPB)&& (data.data.cal.detector!=DMAP_DET_BARREL)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Detector out of range. (%i)",data.data.cal.detector); return DMAP_ERROR_RANGE; } dmap[chain-1].crate[crate-1][slot].data.cal[chan] = data.data.cal; break; case DMAP_BTYPE_CHATDC: if (chan>=DMAP_CHAMBER_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } dmap[chain-1].crate[crate-1][slot].data.chamber[chan] = data.data.chamber; break; case DMAP_BTYPE_QCALTDC: case DMAP_BTYPE_QCALADC: if (chan>=DMAP_QCAL_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } if ((data.data.qcal.detector!=DMAP_DET_QCALA)&& (data.data.qcal.detector!=DMAP_DET_QCALB)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_set","Detector out of range. (%i)",data.data.qcal.detector); return DMAP_ERROR_RANGE; } dmap[chain-1].crate[crate-1][slot].data.qcal[chan] = data.data.qcal; break; default: { ErrorSetF(DMAP_ERROR_CONSISTENCY,"dmap_set","Cannot write in an empty slot."); return DMAP_ERROR_CONSISTENCY; } } return DMAP_ERROR_OK; } /******************************************/ /* Clear function */ /******************************************/ int dmap_clear(unsigned char chain, /* IN: chain */ unsigned char crate, /* IN: crate */ unsigned char slot, /* IN: slot */ unsigned char chan) /* IN: channel */ { int btype; if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_clear","Dmap not initialized!"); return DMAP_ERROR_NOTINIT; } if ((chain<1)||(chain>DMAP_NR_CHAINS)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_clear","Chain nr out of range. (%i)",chain); return DMAP_ERROR_RANGE; } if ((crate<1)||(crate>=dmap[chain-1].nrcrates)) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_clear","Crate nr out of range. (%i)",crate); return DMAP_ERROR_RANGE; } if (slot>=DMAP_BOARDS_PER_CRATE) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_clear","Slot nr out of range. (%i)",slot); return DMAP_ERROR_RANGE; } btype = dmap[chain-1].crate[crate-1][slot].btype; switch (btype) { case DMAP_BTYPE_CALTDC: case DMAP_BTYPE_CALADC: if (chan>=DMAP_CAL_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_clear","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } dmap[chain-1].crate[crate-1][slot].data.cal[chan].detector = DMAP_DET_VOID; break; case DMAP_BTYPE_CHATDC: if (chan>=DMAP_CHAMBER_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_clear","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } dmap[chain-1].crate[crate-1][slot].data.chamber[chan].wire = DMAP_WIRE_VOID; break; case DMAP_BTYPE_QCALTDC: case DMAP_BTYPE_QCALADC: if (chan>=DMAP_QCAL_CHANS_PER_BOARD) { ErrorSetF(DMAP_ERROR_RANGE,"dmap_clear","Channel nr out of range. (%i)",chan); return DMAP_ERROR_RANGE; } dmap[chain-1].crate[crate-1][slot].data.qcal[chan].detector = DMAP_DET_VOID; break; /*default: nothing to do */ } return DMAP_ERROR_OK; } /******************************************/ /* Save function */ /******************************************/ /* write the map in a way it can be reread */ int dmap_write(char *filename, /* i.e. "../data/dmap.dat" */ char *system_name) /* i.e. "System Test" */ { if (dmap_initialized==0) { ErrorSet(DMAP_ERROR_NOTINIT,"dmap_write","Dmap not initialized!"); return DMAP_ERROR_NOTINIT; } { int chain_nr; FILE *fmain; fmain = fopen(filename,"w"); if (fmain==NULL) { ErrorSetF(DMAP_ERROR_UNKNOWN,"dmap_write","Error creating file %s.",filename); return DMAP_ERROR_UNKNOWN; } fprintf(fmain,"%%===========================================\n"); fprintf(fmain,"%% %s\n",system_name); fprintf(fmain,"%%===========================================\n\n"); for (chain_nr=1; chain_nr<=DMAP_NR_CHAINS; chain_nr++) { int crate_nr; int chain_idx = chain_nr-1; fprintf(fmain,"%%=============\n"); fprintf(fmain,"%% Chain %2i\n",chain_nr); fprintf(fmain,"%%=============\n\n"); for (crate_nr=1; crate_nr<dmap[chain_idx].nrcrates; crate_nr++) { int board_nr; int crate_idx = crate_nr-1; fprintf(fmain,"%%=====================\n"); fprintf(fmain,"%% Chain %2i Crate %2i\n",chain_nr,crate_nr); fprintf(fmain,"%%=====================\n\n"); for (board_nr=0; board_nr<DMAP_BOARDS_PER_CRATE; board_nr++) { int btype = dmap[chain_idx].crate[crate_idx][board_nr].btype; fprintf(fmain,"%%==============================\n"); fprintf(fmain,"%% Chain %2i Crate %2i Slot: %2i\n",chain_nr,crate_nr,board_nr); fprintf(fmain,"%%==============================\n\n"); if (btype!=DMAP_BTYPE_VOID) { switch (btype) { case DMAP_BTYPE_CALTDC: case DMAP_BTYPE_CALADC: { int chan_nr; char acard[16]; if (btype==DMAP_BTYPE_CALADC) strcpy(acard,"CALADC"); else strcpy(acard,"CALTDC"); fprintf(fmain,"%%===============================================================================\n"); fprintf(fmain,"%% Chain | Crate | Slot | Chan |DETECT |Module | Plane |Column | Side | Card\n"); fprintf(fmain,"%%===============================================================================\n"); for (chan_nr=0; chan_nr<DMAP_CAL_CHANS_PER_BOARD; chan_nr++) { DMAP_CAL_EL *el; el = &(dmap[chain_idx].crate[crate_idx][board_nr].data.cal[chan_nr]); if (el->detector!=DMAP_DET_VOID) { int amodule,aplane,acolumn,aside; char adetector[16]; amodule = el->module; aplane = el->plane; acolumn = el->column; aside = el->side; if (el->detector==DMAP_DET_ECAPA) strcpy(adetector," ECAPA "); else if (el->detector==DMAP_DET_ECAPB) strcpy(adetector," ECAPB "); else strcpy(adetector," BARR "); fprintf(fmain," %2i %2i %2i %2i %s %2i %2i %2i %2i %s\n", chain_nr,crate_nr,board_nr,chan_nr,adetector,amodule,aplane,acolumn,aside,acard); } } } break; case DMAP_BTYPE_CHATDC: { int chan_nr; fprintf(fmain,"%%=======================================================\n"); fprintf(fmain,"%% Chain | Crate | Slot | Chan |DETECT | Layer | Wire\n"); fprintf(fmain,"%%=======================================================\n"); for (chan_nr=0; chan_nr<DMAP_CHAMBER_CHANS_PER_BOARD; chan_nr++) { DMAP_CHAMBER_EL *el; el = &(dmap[chain_idx].crate[crate_idx][board_nr].data.chamber[chan_nr]); if (el->wire!=DMAP_WIRE_VOID) { int alayer,awire; alayer = el->layer; awire = el->wire; fprintf(fmain," %2i %2i %2i %2i CHAMB %2i %2i\n", chain_nr,crate_nr,board_nr,chan_nr,alayer,awire); } } } break; case DMAP_BTYPE_QCALTDC: case DMAP_BTYPE_QCALADC: { int chan_nr; char acard[16]; if (btype==DMAP_BTYPE_QCALADC) strcpy(acard,"QCALADC"); else strcpy(acard,"QCALTDC"); fprintf(fmain,"%%=======================================================\n"); fprintf(fmain,"%% Chain | Crate | Slot | Chan |DETECT |Module | Card\n"); fprintf(fmain,"%%=======================================================\n"); for (chan_nr=0; chan_nr<DMAP_QCAL_CHANS_PER_BOARD; chan_nr++) { DMAP_QCAL_EL *el; el = &(dmap[chain_idx].crate[crate_idx][board_nr].data.qcal[chan_nr]); if (el->detector!=DMAP_DET_VOID) { int amodule; char adetector[16]; amodule = el->module; if (el->detector==DMAP_DET_QCALA) strcpy(adetector," QCALA "); else strcpy(adetector," QCALB "); fprintf(fmain," %2i %2i %2i %2i %s %2i %s\n", chain_nr,crate_nr,board_nr,chan_nr,adetector,amodule,acard); } } } break; } fprintf(fmain,"\n"); } } } } } return DMAP_ERROR_OK; }