Ignore:
Timestamp:
02/14/05 16:29:56 (20 years ago)
Author:
tbretz
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/mfilter/MFSoftwareTrigger.cc

    r3500 r6459  
    1919!   Author(s): Thomas Bretz, 04/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
    2020!
    21 !   Copyright: MAGIC Software Development, 2000-2003
     21!   Copyright: MAGIC Software Development, 2000-2005
    2222!
    2323!
     
    3030//  This is a class to evaluate a software trigger
    3131//
    32 //  to be called after the calibration (when the number of photons is
    33 //               available for all pixels)
    34 //
    35 // require 2 neighboring pixels (which are not in the outermost ring),
    36 //                       each having at least 'fNumMinPhotons' photons
    37 //
     32//  The number of required pixels is setup by:
     33//   SetNumNeighbors(4)   // default
     34//
     35//  The Threshold is setup by:
     36//    SetThreshold(5)     // default
     37//
     38//  Time window for coincidence:
     39//    SetTimeWindow(3.3)
     40// To switch off time-coincidence use
     41//    SetTimeWindow(-1)
     42//   or
     43//    SetTimeWindow()
     44//
     45//  kSinglePixelsNeighbors <default>
     46//  ----------------------
     47//    Checks whether there is at least one pixel above threshold which
     48//    has fNumNeighbors direct neighbors which are also above threshold.
     49//    The outermost ring of pixels is ignord. Only 'used' pixels are
     50//    taken into account.
     51//
     52//  kAnyPattern
     53//  -----------
     54//    Checks whether it find a cluster of pixels above fThreshold which
     55//    has a size bigger/equal than fNumNeighbors. The layout (pattern) of
     56//    the cluster is ignored. Unmapped pixels are ignored.
     57//
     58//  WARNING: Using trigger type kAllPattern resets the BIT(21) bit
     59//           of all pixels in MCerPhotEvt
     60//
     61//
     62//  Input:
     63//    MCerPhotEvt
     64//    MArrivalTime
     65//    MGeomCam
    3866//
    3967/////////////////////////////////////////////////////////////////////////////
     
    4977
    5078#include "MCerPhotEvt.h"
     79#include "MArrivalTime.h"
    5180
    5281ClassImp(MFSoftwareTrigger);
     
    5988//
    6089MFSoftwareTrigger::MFSoftwareTrigger(const char *name, const char *title)
    61     : fNumMinPhotons(0), fNumNeighbors(2)
     90    : fCam(NULL), fEvt(NULL), fTme(NULL), fThreshold(5),
     91    fTimeWindow(0.5), fNumNeighbors(4), fType(kSinglePixelNeighbors)
    6292{
    6393    fName  = name  ? name  : "MFSoftwareTrigger";
     
    6797// --------------------------------------------------------------------------
    6898//
    69 // Software trigger
    70 //
    71 // require 2 neighboring pixels (which are not in the outermost ring),
    72 //                       each having at least 'fNumMinPhotons' photons
    73 //
     99// This function recursively finds all pixels of one island and sets
     100// BIT(14) for the pixel.
     101//
     102//  1) Check whether a pixel with the index idx exists, is unused
     103//     and has not yet BIT(14) set
     104//  2) Set BIT(14) to the pixel
     105//  3) Loop over all its neighbors taken from the geometry geom. For all
     106//     neighbors recursively call this function (CountPixels)
     107//  4) Sum the number of valid neighbors newly found
     108//
     109// Returns the size of the cluster
     110//
     111Int_t MFSoftwareTrigger::CountPixels(Int_t idx, Float_t tm0) const
     112{
     113    // Try to get the pixel information of a pixel with this index
     114    MCerPhotPix *pix = fEvt->GetPixById(idx);
     115
     116    // If a pixel with this index is not existing... do nothing.
     117    if (!pix)
     118        return 0;
     119
     120    // If pixel already assigned to a cluster
     121    if (pix->TestBit(kWasChecked))
     122        return 0;
     123
     124    if (pix->IsPixelUnmapped())
     125        return 0;
     126
     127    // Assign the new island number num to this used pixel
     128    pix->SetBit(kWasChecked);
     129
     130    // Get the size of this pixel and check threshold
     131    const Double_t size = pix->GetNumPhotons()*fCam->GetPixRatio(idx);
     132    if (size<fThreshold)
     133        return 0;
     134
     135    const Float_t tm1 = (*fTme)[idx];
     136    if (fTimeWindow>0 && TMath::Abs(tm1-tm0)>fTimeWindow)
     137        return 0;
     138
     139    //pix->SetBit(kAboveThreshold);
     140
     141    Int_t num = 1;
     142
     143    // Get the geometry information (neighbors) of this pixel
     144    const MGeomPix &gpix = (*fCam)[idx];
     145
     146    // Now do the same with all its neighbors and sum the
     147    // sizes which they correspond to
     148    const Int_t n = gpix.GetNumNeighbors();
     149    for (int i=0; i<n; i++)
     150        num += CountPixels(gpix.GetNeighbor(i), tm1);
     151
     152    // return size of this (sub)cluster
     153    return num;
     154}
     155/*
     156Int_t MFSoftwareTrigger::CountCoincidencePixels(Int_t idx) const
     157{
     158    // Try to get the pixel information of a pixel with this index
     159    MCerPhotPix *pix = fEvt->GetPixById(idx);
     160
     161    // If a pixel with this index is not existing... do nothing.
     162    if (!pix)
     163        return 0;
     164
     165    // If pixel already assigned to a cluster
     166    if (pix->TestBit(kWasChecked))
     167        return 0;
     168
     169    if (pix->IsPixelUnmapped())
     170        return 0;
     171
     172    // Assign the new island number num to this used pixel
     173    pix->SetBit(kWasChecked);
     174
     175    // Get the size of this pixel and check threshold
     176    const Double_t size = pix->GetNumPhotons();
     177    if (size<fThreshold)
     178        return 0;
     179
     180    Int_t num = 1;
     181
     182    // Get the geometry information (neighbors) of this pixel
     183    const MGeomPix &gpix = (*fCam)[idx];
     184
     185    // Now do the same with all its neighbors and sum the
     186    // sizes which they correspond to
     187    const Int_t n = gpix.GetNumNeighbors();
     188    for (int i=0; i<n; i++)
     189        num += CountPixels(gpix.GetNeighbor(i));
     190
     191    // return size of this (sub)cluster
     192    return num;
     193}
     194*/
     195void MFSoftwareTrigger::ResetBits(Int_t bits) const
     196{
     197    TObject *obj=0;
     198
     199    TIter Next(*fEvt);
     200    while ((obj=Next()))
     201        obj->ResetBit(bits);
     202}
     203
     204// --------------------------------------------------------------------------
     205//
     206// Check if there is at least one pixel which fullfills the condition
     207//
     208Bool_t MFSoftwareTrigger::ClusterTrigger() const
     209{
     210    ResetBits(kWasChecked);
     211
     212    // Reset bit
     213    MCerPhotPix *pix=0;
     214
     215    // We could loop over all indices which looks more straight
     216    // forward but should be a lot slower (assuming zero supression)
     217    TIter Next(*fEvt);
     218    while ((pix=static_cast<MCerPhotPix*>(Next())))
     219    {
     220        // Check if trigger condition is fullfilled for this pixel
     221        const Int_t idx = pix->GetPixId();
     222        if (CountPixels(idx, (*fTme)[idx]) >= fNumNeighbors)
     223            return kTRUE;
     224    }
     225
     226    return kFALSE;
     227}
     228/*
     229Int_t MFSoftwareTrigger::CheckCoincidence(Int_t idx, Float_t tm0) const
     230{
     231    // Try to get the pixel information of a pixel with this index
     232    MCerPhotPix *pix = fEvt->GetPixById(idx);
     233
     234    // If a pixel with this index is not existing... do nothing.
     235    if (!pix)
     236        return 0;
     237
     238    // If pixel already assigned to a cluster
     239    if (pix->TestBit(kWasChecked))
     240        return 0;
     241
     242    if (pix->IsPixelUnmapped())
     243        return 0;
     244
     245    // Assign the new island number num to this used pixel
     246    pix->SetBit(kWasChecked);
     247
     248    const Double_t size = pix->GetNumPhotons();
     249    if (size<fThreshold)
     250        return 0;
     251
     252    const Float_t tm1 = (*fTme)[idx];
     253    if (TMath::Abs(tm1-tm0)>fTimeWindow)
     254        return 0;
     255
     256    pix->SetBit(kIsCoincident);
     257
     258
     259    Int_t num = 1;
     260
     261    // Get the geometry information (neighbors) of this pixel
     262    const MGeomPix &gpix = (*fCam)[idx];
     263
     264    Int_t cnt = 0;
     265
     266    // Now do the same with all its neighbors and sum the
     267    // sizes which they correspond to
     268    const Int_t n = gpix.GetNumNeighbors();
     269    for (int i=0; i<n; i++)
     270    {
     271        const Int_t rc = CheckCoincidence(gpix.GetNeighbor(i), tm0);
     272        if (fEvt->GetPixById(gpix.GetNeighbor(i))->TestBit(kIsCoincident))
     273            cnt++;
     274        num += rc;
     275    }
     276
     277    // return size of this (sub)cluster
     278    return cnt<2 ? 0 : num;
     279
     280}
     281
     282Bool_t MFSoftwareTrigger::MagicLvl1Trigger() const
     283{
     284    // Reset bit
     285    MCerPhotPix *pix=0;
     286
     287    // We could loop over all indices which looks more straight
     288    // forward but should be a lot slower (assuming zero supression)
     289    TIter Next(*fEvt);
     290    while ((pix=static_cast<MCerPhotPix*>(Next())))
     291    {
     292        ResetBits(kWasChecked|kIsCoincident);
     293
     294        const Int_t idx = pix->GetPixId();
     295        if (CheckCoincidence(idx, (*fTme)[idx])<fNumNeighbors)
     296            continue;
     297
     298        return kTRUE;
     299    }
     300    return kFALSE;
     301}
     302*/
     303
     304Bool_t MFSoftwareTrigger::CheckPixel(const MCerPhotPix &pix) const
     305{
     306    if (!pix.IsPixelUsed())
     307        return kFALSE;
     308
     309    if (pix.GetNumPhotons()*fCam->GetPixRatio(pix.GetPixId())<fThreshold)
     310        return kFALSE;
     311
     312    if ((*fCam)[pix.GetPixId()].IsInOutermostRing())
     313        return kFALSE;
     314
     315    return kTRUE;
     316}
     317
     318// --------------------------------------------------------------------------
     319//
     320// Software single pixel coincidence trigger
     321//
    74322Bool_t MFSoftwareTrigger::SwTrigger() const
    75323{
     
    78326    for (Int_t i=0; i<entries; i++)
    79327    {
    80         const MCerPhotPix &pix = (*fEvt)[i];
    81         if (!pix.IsPixelUsed())
     328        const MCerPhotPix &pix0 = (*fEvt)[i];
     329        if (!CheckPixel(pix0))
    82330            continue;
    83331
    84         if (pix.GetNumPhotons()<fNumMinPhotons)
    85             continue;
    86 
    87         // this pixel is used and has the required no.of photons
    88         // check whether this is also true for a neigboring pixel
    89         MGeomPix &gpix = (*fCam)[pix.GetPixId()];
    90         if (gpix.IsInOutermostRing())
    91             continue;
    92 
    93332        Int_t num = 1;
     333
     334        const MGeomPix &gpix = (*fCam)[pix0.GetPixId()];
    94335
    95336        const Int_t nneighbors = gpix.GetNumNeighbors();
    96337        for (Int_t n=0; n<nneighbors; n++)
    97338        {
    98             const Int_t id = gpix.GetNeighbor(n);
    99             if (!fEvt->IsPixelUsed(id))
     339            const Int_t idx1 = gpix.GetNeighbor(n);
     340            if (!CheckPixel(*fEvt->GetPixById(idx1)))
    100341                continue;
    101342
    102             if ((*fCam)[id].IsInOutermostRing())
    103                 continue;
    104 
    105             const Double_t photons = fEvt->GetPixById(id)->GetNumPhotons();
    106             if (photons >= fNumMinPhotons)
    107                 if (++num==fNumNeighbors)
    108                     return kTRUE;
     343            if (fTimeWindow>0)
     344            {
     345                const Float_t t0 = (*fTme)[pix0.GetPixId()];
     346                const Float_t t1 = (*fTme)[idx1];
     347
     348                if (TMath::Abs(t0-t1)>fTimeWindow)
     349                    continue;
     350            }
     351
     352            if (++num==fNumNeighbors)
     353                return kTRUE;
    109354        }
    110355    }
     
    132377    }
    133378
     379    fTme = (MArrivalTime*)pList->FindObject("MArrivalTime");
     380    if (!fTme)
     381    {
     382        *fLog << err << "MArrivalTime not found... aborting." << endl;
     383        return kFALSE;
     384    }
     385
     386
    134387    memset(fCut, 0, sizeof(fCut));
    135388
     
    143396Int_t MFSoftwareTrigger::Process()
    144397{
    145     fResult = SwTrigger();
     398    switch (fType)
     399    {
     400    case kSinglePixelNeighbors:
     401        fResult = SwTrigger();
     402        break;
     403    case kAnyPattern:
     404        fResult = ClusterTrigger();
     405        break;
     406    }
    146407
    147408    fCut[fResult ? 0 : 1]++;
     
    157418    if (GetNumExecutions()==0)
    158419        return kTRUE;
     420
     421    TString type;
     422    switch (fType)
     423    {
     424    case kSinglePixelNeighbors:
     425        type = " single pixel trigger";
     426        break;
     427    case kAnyPattern:
     428        type = " any pattern trigger";
     429        break;
     430    }
    159431
    160432    *fLog << inf << endl;
     
    164436    *fLog << " " << setw(7) << fCut[0] << " (" << setw(3) ;
    165437    *fLog << (int)(fCut[0]*100/GetNumExecutions());
    166     *fLog << "%) Evts fullfilled software trigger";
    167     *fLog << " (NumPhotons>=" << fNumMinPhotons << ", NumNeighbors>=";
    168     *fLog << (int)fNumNeighbors << ")" << endl;
     438    *fLog << "%) Evts fullfilled" << type;
     439    *fLog << " (Thresh>=" << fThreshold << ", Num>=";
     440    *fLog << (int)fNumNeighbors << ", Win=" << fTimeWindow << ")" << endl;
    169441    *fLog << " " << setw(7) << fCut[1] << " (" << setw(3) ;
    170442    *fLog << (int)(fCut[1]*100/GetNumExecutions());
    171     *fLog << "%) Evts didn't fullfill software trigger."  << endl;
     443    *fLog << "%) Evts didn't fullfill" << type << "."  << endl;
    172444
    173445    return kTRUE;
    174446}
     447
     448// --------------------------------------------------------------------------
     449//
     450// Read the setup from a TEnv, eg:
     451//   MFSoftwareTrigger.Threshold:    5
     452//   MFSoftwareTrigger.NumNeighbors: 4
     453//   MFSoftwareTrigger.TimeWindow: 3.3
     454//   MFSoftwareTrigger.TriggerType: SinglePixel, AnyPattern
     455//
     456// To switch off time-coincidence use
     457//   MFSoftwareTrigger.TimeWindow: -1
     458//
     459Int_t MFSoftwareTrigger::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
     460{
     461    Bool_t rc = kFALSE;
     462    if (IsEnvDefined(env, prefix, "Threshold", print))
     463    {
     464        rc = kTRUE;
     465        SetThreshold(GetEnvValue(env, prefix, "Threshold", fThreshold));
     466    }
     467    if (IsEnvDefined(env, prefix, "NumNeighbors", print))
     468    {
     469        rc = kTRUE;
     470        SetNumNeighbors(GetEnvValue(env, prefix, "NumNeighbors", fNumNeighbors));
     471    }
     472    if (IsEnvDefined(env, prefix, "TimeWindow", print))
     473    {
     474        rc = kTRUE;
     475        SetTimeWindow(GetEnvValue(env, prefix, "TimeWindow", fTimeWindow));
     476    }
     477
     478    if (IsEnvDefined(env, prefix, "TriggerType", print))
     479    {
     480        TString dat = GetEnvValue(env, prefix, "TriggerType", "");
     481        dat = dat.Strip(TString::kBoth);
     482        dat.ToLower();
     483
     484        if (dat == (TString)"singlepixel")
     485            SetTriggerType(kSinglePixelNeighbors);
     486        if (dat == (TString)"anypattern")
     487            SetTriggerType(kAnyPattern);
     488
     489        rc = kTRUE;
     490    }
     491
     492    return rc;
     493}
Note: See TracChangeset for help on using the changeset viewer.