///////////////////////////////////////////////// // TCHIEvent IMPLEMENTATION // e.d.f. November 2010 // ver. 1.0 Chimera Event UnPacker // rev 3/2011 ///////////////////////////////////////////////// #include "TCHIEvent.h" int TCHIEvent::fnumerrors=0; TCHIEvent *gevent = 0; const int MINFIR = 2; //Constructor TCHIEvent::TCHIEvent(string filename, int vmecrates) : fvmenum(vmecrates) { ffilename = filename; fcorrectoffset = true; fevtlen = 0; fstartevt = 0; fendevt = 0; fpostel = -1; ftsl=0; ftsm=0; ftsh=0; ftotfired = 0; // fTelFired.reserve(100); fRawmulti = 0; fTDCmulti = 0; for(int i=0; iIsGeomDefined()) { cout<<"Found a valid Chimera geometry setup"<0) { cout<<"Found "< map } void TCHIEvent::Gen_list_par(int row, TCHIParam *par) { int pid; TCHIParam *bp = new TCHIParam; *bp = *par; if((bp->fcrate == -1 || bp->fboard == -1 || bp->faddr==-1 || bp->fmod==-1)) { cout<<"Not valid parameter definition at line "<pgetpid(bp->fcrate,bp->fboard,bp->faddr); /* PID definition */ fpar_list[pid] = new TCHIParam; *fpar_list[pid] = *par; fpar_list[pid]->fpid = pid; if(fpar_list[pid]->fnumtel != -1) { fpar_list[pid]->fpostel = fpostel; } else { fpar_list[pid]->fpostel = -1; } // associate a name to a pid number fpidnames[fpar_list[pid]->fname] = pid; //update the telescope number int nt = fpar_list[pid]->fnumtel; if(nt >= 0) { int res = Upgrade_ListTel(nt,pid); if(res<0)cout<<"Error in Telescope definition: "<=MAX_TELES)return -1; if(ftel_list[nt] == 0) { TCHITeles *tel = new TCHITeles; ftel_list[nt] = tel; } else { ftel_list[nt]->fnumparam++; } int pos = fpar_list[pid]->fpostel; ftel_list[nt]->fptel[pos] = pid; ftel_list[nt]->flmulti = 0; return 0; } int TCHIEvent::pgetpid(int crate, int board, int addr) /* return the pid number given the VME crate, board and address */ { return (1 + addr + board*MAX_ADDR + crate*MAX_BOARD*MAX_ADDR); } int TCHIEvent::GetPidvalue(const char *name) { int pid; map::iterator it = fpidnames.find((char *)name); if(it!=fpidnames.end()) { pid = (*it).second; } else { pid = -1; } return pid; } int TCHIEvent::GetEvent(int *start) { int len = *start / 2 + 2; fevtlen = len; fstartevt = start; fendevt = start + len - 1; return len; } // set the event parameters for standard chimera header int TCHIEvent::GetEvent(int *start, int *stop, int len) { fevtlen = len; fstartevt = start; fendevt = stop; return len; } //************************************************ // // CHIMERA readout for Chimera-MBS event structure // //************************************************ int TCHIEvent::ProcessCurrentEventMBS(int *buffer) { float const OFFSET=80.0, GAIN = 8.2; // int *estart; //int *buffer; int crate,pcount,plen,cratenum, endevt; unsigned int pident; int vnb, nextw, bcrate, endqdc, pid; float offset, gain; Cheadw chead; Cdatumw cdatum; /* if(fstartevt == 0 || fevtlen==0) { cout<<"Bad or not existing event"<> 8; chead.board = (buffer[i] & mask1[3]) >> 27; bcrate = (buffer[i] & mask1[6])>>16; // the counter is at end chead.counter = (buffer[i+chead.mult+1] & mask1[1]); vnb = 1; } } // candidate legacy caen board if(vnb!=1 && ((buffer[i] & mask[0]) == mask[0])) { chead.mult =(buffer[i] & mask[2]) >> 16; if(chead.mult == 0)chead.mult = 64; chead.board = (buffer[i] & mask[3]) >> 23; chead.counter = buffer[i] & mask[1]; // cout<<"crate1:"<< chead.board <<" "<> 16); } else if(vnb == 1) { cdatum.valore = (buffer[i] & mask1[4]); cdatum.channel =((buffer[i] & mask1[5]) >> 16); } pid = pgetpid(cratenum, chead.board, cdatum.channel); if((pid>MAX_PID_NUMBER) || (pid<0)) continue; if(fpar_list[pid]==0) { continue; //parameter not declared in list } if(fpar_list[pid]->fmod==TDC || fpar_list[pid]->fmod==ADC) cdatum.range = 1; else cdatum.range = (buffer[i] & mask[6]) >> 12; // pedestal partial or total suppression request if(fpar_list[pid]->fpedsuppr > 0.0 && cdatum.range == 0) { if(cdatum.valore < fpar_list[pid]->fpedestal+ fpar_list[pid]->fpedsuppr ) { continue; } } data_chimera[num].fpid = pid; data_chimera[num].fnt = -1; //start telescope value if(cdatum.range==0) { data_chimera[num].fval_hg = cdatum.valore; offset = (fpar_list[pid]->foffset>0) ? fpar_list[pid]->foffset : OFFSET; gain = (fpar_list[pid]->fgain>0) ? fpar_list[pid]->fgain : GAIN; // cout << pid <<" " << num <<" "<fvalue = num; // telescope's list filling int nt = fpar_list[pid]->fnumtel; if(nt != -1) { ftel_list[nt]->flmulti++; data_chimera[num].fnt = nt; // telescope is filled if at least two parameters fired if(ftel_list[nt]->flmulti == MINFIR) { fTelFired.push_back(nt); fRawmulti++; } } num++; if(num>=MAX_FIRED) { cout<<"Too much fired parameters "<fptel[TOF30]; int stof = ftel_list[nt]->fptel[TOFSi]; int t1=0; int t2=0; if(ptof>0)t1 = Get_PidFired(ptof); if(stof>0)t2 = Get_PidFired(stof); if(t1>0 || t2>0 )fTDCmulti++; } return fTDCmulti; } // clear all: clear fired parameters in the fpar_list void TCHIEvent::Clear_fired_param(int nummax) { int k; if(nummax==0)nummax=ftotfired; for(k=0; kfvalue =-1; int nt = data_chimera[k].fnt; if(nt>=0) { ftel_list[nt]->flmulti = 0; } } fTelFired.clear(); fRawmulti = 0; fTDCmulti = 0; ftotfired = 0; } void TCHIEvent::GetTiMeStamp(int *tsl, int *tsm, int *tsh) { *tsl = ftsl; *tsm = ftsm; *tsh = ftsh; } // Get raw data values for a given telescope number // or -1 if telescope is not fired int TCHIEvent::Get_Data_Telescope(int nt, VAR xpar, VAR ypar, egain xg, egain yg , int *x, int *y) { int pidx=0, pidy=0; int xval=0, yval=0; int num; if(ftel_list[nt]==0)return -1; int lmulti = ftel_list[nt]->flmulti; if(lmulti==0)return -1; if(xpar != NONE) pidx = ftel_list[nt]->fptel[xpar]; if(ypar != NONE) pidy = ftel_list[nt]->fptel[ypar]; if(pidx>0) { num = Get_PidFired(pidx); if(num!=-1) { if(xg == LG) { xval = data_chimera[num].fval_lg; } else { xval = data_chimera[num].fval_hg; } } } if(pidy>0) { num = Get_PidFired(pidy); if(num!=-1) { if(yg == LG) { yval = data_chimera[num].fval_lg; } else { yval = data_chimera[num].fval_hg; } } } *x = xval; *y = yval; return 0; } // Given pid number return the position in the database of a fired // parameter or -1 if parameter is not fired int TCHIEvent::Get_PidFired(int pid) { int val; if( (val = fpar_list[pid]->fvalue) != -1) { return val; } else return -1; } // return channel given parameter's pid number int TCHIEvent::Get_Value(int pid, egain gain) { int value = -1; int num = Get_PidFired(pid); if(num != -1) { if(gain==LG) value = data_chimera[num].fval_lg; else value = data_chimera[num].fval_hg; } return value; } // return channel given parameter's name int TCHIEvent::Get_Value(const char *name, egain gain) { int value = -1; int pid = GetPidvalue(name); if(pid<0)return -1; int num = Get_PidFired(pid); if(num != -1) { if(gain==LG) value = data_chimera[num].fval_lg; else value = data_chimera[num].fval_hg; } return value; } //getting param type and telescope number restitutes the parameter's name char *TCHIEvent::GetTelesName(VAR par, int tel) { static char name[32]; int pid; strcpy(name,""); if(ftel_list[tel] != 0 ) { pid = ftel_list[tel]->fptel[par]; if(pid != 0) strcpy(name, fpar_list[pid]->fname); } return name; } int TCHIEvent::GetTelesPid(VAR par, int tel) { int pid=0; if(ftel_list[tel] != 0 ) { pid = ftel_list[tel]->fptel[par]; } return pid; } int TCHIEvent::Get_Pedestal_Data(const char *filename) { int pid; float pedestal, sigma, supp; char line[80]; char name[16]; ifstream fd(filename); if(!fd) { cout<<"Warning: Pedestal file "<fpid == pid) { fpar_list[pid]->fpedestal = pedestal; fpar_list[pid]->fpedsuppr = supp; } break; } } fd.close(); cout<<"Read "<fpid == pid) { fpar_list[pid]->foffset = offset; fpar_list[pid]->fgain = gain; } break; } } fclose(fd); cout<<"Read "<IsGeomDefined())return; for(int i=0; ifptel[TOF30]; if(ptof>0) { if(Get_PidFired(ptof)>=0) { m = fgeometry->GetGeom(); s_phi = m[nt].Phi + (0.5-fgeometry->Rndm())*(m[nt].DeltaPhi); if(s_phi > PI) s_phi=-2*PI+s_phi; if(s_phi <-PI) s_phi= 2*PI+s_phi; s_theta = fgeometry->Rndm() * (m[nt].ThetaMax - m[nt].ThetaMin) + m[nt].ThetaMin; *x = s_theta*cos(s_phi)*180.0/PI; *y = s_theta*sin(s_phi)*180.0/PI; } } } } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// TCHIGeometry::TCHIGeometry(string filename) { char temp[256]; int ring, Nmod; float Dist, Tmin, Tmax , Theta, CesioLen, deltaphi; int ntel = 0; float PI = 3.14159; fseed = 65539; FILE *fd = fopen(filename.c_str(),"r"); if(fd==NULL) { fgeom = false; return; } while(fscanf(fd,"%[^\n]\n",temp)>0) { if(temp[0]=='#') continue; sscanf(temp,"%d %f %f %f %d %f",&ring,&Dist,&Tmin,&Tmax,&Nmod,&CesioLen); Tmin *= PI/180.0; Tmax *= PI/180.0; Theta=0.5*(Tmax+Tmin); deltaphi=2*PI/Nmod; for(int i=0; i PI) fm[ntel].Phi=-2*PI+fm[ntel].Phi; if(fm[ntel].Phi<-PI) fm[ntel].Phi= 2*PI+fm[ntel].Phi; fm[ntel].DeltaPhi = deltaphi; ntel++; } } fgeom = true; fclose(fd); } float TCHIGeometry::Rndm() { float random; unsigned int jy; /* Machine independent random number generator. Produces uniformly-distributed floating points between 0 and 1. Identical sequence on all machines of >= 32 bits. Periodicity = 10**8 Universal version (Fred james 1985). generates a number in [0,1] */ const float kCONS = 4.6566128730774E-10; const int kMASK31 = 2147483647; const int kMASK24 = 2147483392; fseed *= 69069; /* keep only lower 31 bits */ fseed &= kMASK31; /* Set lower 8 bits to zero to assure exact float */ jy = fseed & kMASK24; random = kCONS*jy; return random; }