//############################################################################################################################################################# // // filter.c # by Emiliano Mocchiutti (2005/11/25) // // Changelog: // // (2006/02/24) Cannot load tracker level0 and level2 data simultaneously, fixed. // //############################################################################################################################################################# // // Template for the event selection using the EventViewer. The function must be called "filter" while the filename where the function is defined can be anyone. // //############################################################################################################################################################# // // The idea of the event selection is the following: // 1) you must know which kind of data the EventViewer program is using (for example tracker level0, level1 or level2 data?) // 2) depending on the available data you can define your selection. // 3) information about data used can be found in the structure "level" which contains the following variables: // typedef struct Levels { // Int_t calo; // if equal to 0 calorimeter level 0 , if equal to 1 calorimeter level 1 data. // Int_t calol2; // for the moment this is always 0 // Int_t tof; // tof/trigger level 1 or level 0 data // Int_t track; // tracker level 1 or level 0 data // Int_t track2; // if set to one there are tracker level2 data // Int_t s4; // S4 level 1 or level0 data // Int_t ac; // AC level 1 or level0 data // Int_t nd; // always 0 for the moment // } level; // evno is the event number to be processed. // All data coming from yoda are stored in the tree called "otr", tree "ttr" contains only level2 tracker data. // 4) to learn how to change things look at examples below. // 5) to stop the eventviewer this function must return 1 as value, when returning 0 means go on searching. // 6) is it possible to combine information from different detectors. // int filter(Int_t evno, TTree *otr, TTree *ttr, Levels & level){ // // example n. 1 // select events where the energy deposit in S4 is greater than 0.7 MIP // Bool_t S4 = true; // // check the data level // if ( level.s4 == 0 ) { S4 = false; // // determine in which branch we can find S4 data in the tree otr. // pamela::S4::S4Event *s4 = 0; otr->SetBranchAddress("S4.Event", &s4); otr->GetEntry(evno); // // if we have level0 data we must calibrate the data to make a selection in MIP. // Float_t s4data = ((float)s4->S4_DATA -32.) * 0.29; // // if the condition is satisfied S4 is true. // if ( s4data>0.7 ) S4 = true; }; // // example n. 2 // select events with one or more tracks // Bool_t TRACKER = true; // // check we have tracker LEVEL2 data // if ( level.track2 == 1 ){ TRACKER = false; // // access tracker level2 data, store variables in the structure trk. // struct Tracklev2 trk; settrklev2(ttr,trk); // // get entry, here we are assuming we have syncronized data. // ttr->GetEntry(evno); // if ( trk.ntrk > 0 ){ // TRACKER = true; // // example of how to calculate rigidity from deflection and select negative particles with rigidity less than 1 GV: // // Float_t rig = 0.; // // notice that in the structure trk columns and rows of matrixes are inverted respect to the fortran style al[0][4] is deflection for the first track // al[1][4] would be deflection for the second track, etc. // // if ( trk.al[0][4] != 0. ) rig = 1./trk.al[0][4]; // if ( abs(rig) < 1. ) TRACKER = true; }; }; // // example n. 3 // select events with 6 hist in the X-view of the tracker and 6 hit in the Y-view of the tracker // Bool_t TRACKER2 = true; // if ( level.track == 0 ){ TRACKER2 = false; Int_t fnclx = 0; Int_t fncly = 0; pamela::tracker::TrackerEvent *ttrk = 0; otr->SetBranchAddress("Tracker.Event", &ttrk); otr->GetEntry(evno); for (Int_t l = 0; l<12; l++){ Int_t planeno = ttrk->DSPnumber[l]-1; if ( planeno < 0 || planeno > 11 ) planeno = 0; if ( planeno >= 0 ) { if ( (planeno+1)%2 ){ for (Int_t m = 0; m<3; m++){ if ( ttrk->signcluster[l][m] != 0. ){ fncly++; }; }; } else { for (Int_t m = 0; m<3; m++){ if ( ttrk->signcluster[l][m] != 0. ){ fnclx++; }; }; }; }; }; if ( fnclx == 6 && fncly == 6 ) TRACKER2 = true; }; // // example n. 4 // select events with qtot greater than 100 and nstrip greater than 100 in the calorimeter (interacting particles) // Bool_t CALO = true; // // check if we have calorimeter level1 data // if ( level.calo == 1 ){ CALO = false; CalorimeterLevel1 *calo = new CalorimeterLevel1(); otr->SetBranchAddress("CaloLevel1.Event", &calo); otr->GetEntry(evno); if ( calo->qtot > 100 && calo->nstrip > 100) CALO = true; }; // // example n. 5 // select calorimeter selftrigger events // Bool_t TRIGGER = true; if ( level.tof == 0 || level.tof == 1 ){ // Bool_t TRIGGER = false; // // define where to find in the tree otr the Trigger.Event branch // pamela::trigger::TriggerEvent *trig = 0; otr->SetBranchAddress("Trigger.Event", &trig); // // get the entry number "evno" passed by the main EventViewer program // otr->GetEntry(evno); // // check the first element of the variable patterntrig which tell us if this one is a calorimeter trigger // if ( trig->patterntrig[0] ) { // // set the boolean variable TRIGGER to true. Instead of setting this variable it is possible to return(1) here. // TRIGGER = true; }; // // example if one want to select S4/pulser triggers // //if ( trig->patterntrig[1] & (1<<0) ) TRIGGER = true; }; // // example n. 6 // select events with AC hits // Bool_t AC = true; // // in the case of level0 data // if ( level.ac == 0){ AC = false; pamela::anticounter::AnticounterEvent *ace = 0; otr->SetBranchAddress("Anticounter.Event", &ace); otr->GetEntry(evno); Int_t hitmapA = 0; Int_t hitmapB = 0; // // hitmap variable contain the information // hitmapA = ace->hitmap[0]; hitmapB = ace->hitmap[1]; if ( hitmapA || hitmapB ) AC = true; }; // // in the case of level1 data // if ( level.ac == 1){ AC = false; AnticounterLevel1 *ace = new AnticounterLevel1(); otr->SetBranchAddress("AcLevel1.Event", &ace); otr->GetEntry(evno); Int_t hitmapA = 0; Int_t hitmapB = 0; hitmapA = ace->hitmap[0]; hitmapB = ace->hitmap[1]; if ( hitmapA || hitmapB ) AC = true; }; // // example n. 7 // select events in which we have at least one AC hit outside the trigger time window (we need level1 data) // Bool_t AC2 = true; if ( level.ac == 1){ AC2 = false; AnticounterLevel1 *ace = new AnticounterLevel1(); otr->SetBranchAddress("AcLevel1.Event", &ace); otr->GetEntry(evno); Int_t hitstatusA = 0; Int_t hitstatusB = 0; Int_t hitmapA = 0; Int_t hitmapB = 0; hitmapA = ace->hitmap[0]; hitmapB = ace->hitmap[1]; hitstatusA = ace->hitstatus[0]; hitstatusB = ace->hitstatus[1]; Int_t deltaA = hitstatusA - hitmapA; Int_t deltaB = hitstatusB - hitmapB; if ( deltaA || deltaB ) AC2 = true; }; // // example n. 8 // select events with one or more detected neutrons: // Bool_t ND = true; if ( level.nd == 0){ ND = false; Int_t tmpSize; Int_t nTrig = 0; pamela::neutron::NeutronEvent *ne = 0; pamela::neutron::NeutronRecord *nr = 0; otr->SetBranchAddress("Neutron.Event", &ne); otr->GetEntry(evno); tmpSize = ne->Records->GetEntries(); for (Int_t j = 0; j < tmpSize; j++){ nr = (pamela::neutron::NeutronRecord*)ne->Records->At(j); nTrig += (int)nr->trigPhysics; }; if ( nTrig > 0 ) ND = true; }; // // Here we can use the boolean variables and decide if the event passed the selecion or not. // // if the event pass the selection return one, zero otherwise. // // // Some examples: // // A - select only calorimeter selftrigger events // // if ( TRIGGER ) return(1); // B - select calorimeter self-trigger events with at least one fitted track: // // if ( TRIGGER && TRACKER ) return(1); // C - select events with at least one track (default behaviour so it is uncommented) // if ( TRACKER ) return(1); // D - select interacting events in the calorimeter // // if ( CALO ) return(1); // E - select events with hit in the anticounters // // if ( AC ) return(1); // F - select events with energy release in S4 greater than 0.7 MIPs, at least one track, no hit in the anticounters and at least one neutron detected: // // if ( S4 && TRACKER && !AC && ND ) return(1); // // if nothing match, return 0. // return(0); };