// stopNode.h // This is v2 of the farfalla Stop Node written by Chris Orth // It contains all of the information of MACRO equipment 40 // // v1 had words in a different order from the data, which proved // to be kind of troublesome when I switched over to single // arrays. // Trigger face times are accessible through the variable // trigTime[SM][int] // where int can be one of the following: // STOP_TOHM=0; // STOP_ERP=1; // STOP_STM=2; // STOP_FMT=3; // STOP_CSPAM=4; // STOP_LIP=5; // STOP_ISTOP=6; // STOP_HIP=7; // // these variables are declared in this header as static to reduce // the chance of conflict with other variables in your code // // Similarly, the tohm Face times are as follows: // faceTime[SM][int] // here, int can be: // STOP_CENTER=0; // STOP_BOTTOM=1; // STOP_WEST=2; // STOP_EAST=3; // STOP_NORTH=4; // STOP_TOP=5; // STOP_SMPLUS=6; // STOP_SMMINUS=7; // // The trigger and tohm registers are accessible through // trigRegister[SM] // tohmRegister[SM] // // Inline functions: // // print = the usual, but it tries to use the dash print level // to do this, set stopNode->printLevel=dash_pri_lev() // in the calling routine // // smTest = returns 1 if that sm has any trigger times, 0 otherwise // #include #include #include // trigger aliases, use these to access specific timing // info in the stoptime[SM][TRIGALIAS] arrays // Trigger Word aliases static int STOP_TOHM=0; static int STOP_ERP=1; static int STOP_STM=2; static int STOP_FMT=3; static int STOP_CSPAM=4; static int STOP_LIP=5; static int STOP_ISTOP=6; static int STOP_HIP=7; static String STOP_TRIG_NAME[8]; // Tohm Face Word Aliases static int STOP_CENTER=0; static int STOP_BOTTOM=1; static int STOP_WEST=2; static int STOP_EAST=3; static int STOP_NORTH=4; static int STOP_TOP=5; static int STOP_SMMINUS=6; static int STOP_SMPLUS=7; static String STOP_FACE_NAME[8]; // Tohm Face Register bit aliases static const int STOP_COINC_BIT=0; static const int STOP_CENTER_BIT=1; static const int STOP_BOTTOM_BIT=2; static const int STOP_WEST_BIT=3; static const int STOP_EAST_BIT=4; static const int STOP_NORTH_BIT=5; static const int STOP_TOP_BIT=6; static const int STOP_SMMINUS_BIT=7; static const int STOP_SMPLUS_BIT=8; static const int STOP_SMMINUS_COINC_BIT=9; static const int STOP_SMPLUS_COINC_BIT=10; static const int STOP_JUNK_I_BIT=11; static const int STOP_JUNK_II_BIT=12; static const int STOP_JUNK_III_BIT=13; static const int STOP_JUNK_IV_BIT=14; static const int STOP_JUNK_V_BIT=15; static String STOP_FACE_BIT_NAME[16]; // Trigger Register Aliases static const int STOP_TOHM_BIT=0; static const int STOP_ERP_BIT=1; static const int STOP_STM_BIT=2; static const int STOP_FMT_BIT=3; static const int STOP_CSPAM_BIT=4; static const int STOP_LIP_BIT=5; static const int STOP_ISTOP_BIT=6; static const int STOP_HIP_BIT=7; static const int STOP_ERP_CHK_BIT=8; static const int STOP_STM_CHK_BIT=9; static const int STOP_TOHM_CHK_BIT=10; static const int STOP_FMT_CHK_BIT=11; static const int STOP_CSPAM_CHK_BIT=12; static const int STOP_LIP_CHK_BIT=13; static const int STOP_ISTOP_CHK_BIT=14; static const int STOP_HIP_CHK_BIT=15; static String STOP_TRIG_BIT_NAME[16]; // These overflow values *may* change from run to run // If/when they are more stable, these params may // be useful for time-based searches static const int TRIG_OVERFLOW[6]= { 10016, 10000, 10016, 10000, 10016, 10016}; static const int TOHM_OVERFLOW[6]= { 10000, 10000, 10016, 10002, 9744, 10002}; static F_NodeType stopType = "STOP"; class stopNode : public F_Node { public: stopNode() { type = stopType; version = 2; fillArrayNames();} // Time info for triggers unsigned char version; unsigned short trigTime[6][8]; unsigned short faceTime[6][8]; unsigned short trigRegister[6]; //bitpattern of what triggered the StopMaster unsigned short tohmRegister[6]; //bitpattern of the SMT face triggers. virtual inline void fillArrayNames() { // I decided to fill these here, because I expect that the stop // master manual is wrong about the bit orders, and it will be // very easy this way to simply change the value of the STOP* // array indices. I learned the hard way that these cannot go // in the main body of the class because they are not interpretted // as initializations, but as redeclarations. // trigger names STOP_TRIG_NAME[STOP_TOHM]="TOHM "; STOP_TRIG_NAME[STOP_ERP] ="ERP "; STOP_TRIG_NAME[STOP_CSPAM]="CSPAM"; STOP_TRIG_NAME[STOP_STM]="STM "; STOP_TRIG_NAME[STOP_FMT]="FMT "; STOP_TRIG_NAME[STOP_HIP]="HIP "; STOP_TRIG_NAME[STOP_LIP]="LIP "; STOP_TRIG_NAME[STOP_ISTOP]="ISTOP"; //tohm face names STOP_FACE_NAME[STOP_BOTTOM] ="BOT "; STOP_FACE_NAME[STOP_CENTER] ="CENT "; STOP_FACE_NAME[STOP_WEST] ="WEST "; STOP_FACE_NAME[STOP_EAST] ="EAST "; STOP_FACE_NAME[STOP_NORTH] ="NORTH"; STOP_FACE_NAME[STOP_TOP] ="TOP "; STOP_FACE_NAME[STOP_SMPLUS] ="SM+ "; STOP_FACE_NAME[STOP_SMMINUS]="SM- "; //trigger bit names STOP_TRIG_BIT_NAME[STOP_TOHM_BIT]="TOHM "; STOP_TRIG_BIT_NAME[STOP_ERP_BIT]="ERP "; STOP_TRIG_BIT_NAME[STOP_STM_BIT]="STM "; STOP_TRIG_BIT_NAME[STOP_CSPAM_BIT]="CSPAM "; STOP_TRIG_BIT_NAME[STOP_FMT_BIT]="FMT "; STOP_TRIG_BIT_NAME[STOP_LIP_BIT]="LIP "; STOP_TRIG_BIT_NAME[STOP_ISTOP_BIT]="ISTOP "; STOP_TRIG_BIT_NAME[STOP_HIP_BIT]="HIP "; STOP_TRIG_BIT_NAME[STOP_ERP_CHK_BIT]="ERPCk "; STOP_TRIG_BIT_NAME[STOP_STM_CHK_BIT]="STMCk "; STOP_TRIG_BIT_NAME[STOP_TOHM_CHK_BIT]="TOHMCk "; STOP_TRIG_BIT_NAME[STOP_FMT_CHK_BIT]="FMTCk "; STOP_TRIG_BIT_NAME[STOP_CSPAM_CHK_BIT]="CSPAMCk "; STOP_TRIG_BIT_NAME[STOP_LIP_CHK_BIT]="LIPCk "; STOP_TRIG_BIT_NAME[STOP_ISTOP_CHK_BIT]="ISTOPCk "; STOP_TRIG_BIT_NAME[STOP_HIP_CHK_BIT]="HIPCk "; // face bit names STOP_FACE_BIT_NAME[STOP_COINC_BIT] = "COINC "; STOP_FACE_BIT_NAME[STOP_BOTTOM_BIT] = "BOTT "; STOP_FACE_BIT_NAME[STOP_CENTER_BIT] = "CENT "; STOP_FACE_BIT_NAME[STOP_EAST_BIT] = "EAST "; STOP_FACE_BIT_NAME[STOP_WEST_BIT] = "WEST "; STOP_FACE_BIT_NAME[STOP_NORTH_BIT] = "NORTH "; STOP_FACE_BIT_NAME[STOP_TOP_BIT] = "TOP "; STOP_FACE_BIT_NAME[STOP_SMMINUS_BIT] = "SM- "; STOP_FACE_BIT_NAME[STOP_SMPLUS_BIT] = "SM+ "; STOP_FACE_BIT_NAME[STOP_SMMINUS_COINC_BIT] = "SM-C "; STOP_FACE_BIT_NAME[STOP_SMPLUS_COINC_BIT] = "SM+C "; STOP_FACE_BIT_NAME[STOP_JUNK_I_BIT] = "JUNK1 "; STOP_FACE_BIT_NAME[STOP_JUNK_II_BIT] = "JUNK2 "; STOP_FACE_BIT_NAME[STOP_JUNK_III_BIT] = "JUNK3 "; STOP_FACE_BIT_NAME[STOP_JUNK_IV_BIT] = "JUNK4 "; STOP_FACE_BIT_NAME[STOP_JUNK_V_BIT] = "JUNK5 "; } // This routine tells if there is stop data for a given SM virtual inline int smTest(int SM) { if(SM<0 || SM>5) return 0; for(int trigger = 0; trigger <=7; trigger++) if(trigTime[SM][trigger])return 1; return 0; } virtual inline void print(ostream& o) { static int SM; BitString trigBits[6]; // these contain the same info as "register" BitString smtBits[6]; // variables, only they are convenient bitstrings. for(SM=0 ; SM<6; SM++) { trigBits[SM]=shorttoBitString(trigRegister[SM]); smtBits[SM]=shorttoBitString(tohmRegister[SM]); } o << "Stop Master Node version:" << (short) version << endl << endl; o << " Trig | Relative Time in 100ns units" << endl; o << " |"; for(int testSM=0; testSM<6; testSM++) { if(smTest(testSM)) o << " SM" << testSM+1 << " |"; } o << endl; for(int triggernum=0; triggernum<8; triggernum++) { o << STOP_TRIG_NAME[triggernum] << " | "; for(SM=0; SM<6 ; SM++) if(smTest(SM))o << setw(7) << trigTime[SM][triggernum] << " | "; o << endl; } for(int facenum=0; facenum<8; facenum++) { o << STOP_FACE_NAME[facenum] << " | "; for(SM=0; SM<6 ; SM++) if(smTest(SM))o << setw(7) << faceTime[SM][facenum] << " | "; o << endl; } o << "======="; for(SM=0;SM<6;SM++) if(smTest(SM))o<<"=========="; o << endl; for(SM=0; SM<6; SM++) { if(trigRegister[SM]!=0)o<<"SM" << SM+1 << " Trigger Bits: "; for(int trigbit=0; trigbit < 16; trigbit++) if(trigRegister[SM] & (1<5 || bitnum<0 || bitnum>15)return 0; // always allow for the stupid return (trigRegister[SM] & (1<5 || bitnum<0 || bitnum>15)return 0; // always allow for the stupid return (tohmRegister[SM] & (1<