Ignore:
Timestamp:
07/25/02 09:14:36 (22 years ago)
Author:
tbretz
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/manalysis/MHillas.cc

    r1394 r1434  
    1919!   Author(s): Harald Kornmayer 1/2001
    2020!   Author(s): Rudolf Bock     10/2001 <mailto:Rudolf.Bock@cern.ch>
     21!   Author(s): Wolfgang Wittek  6/2002 <mailto:wittek@mppmu.mpg.de>
    2122!
    2223!   Copyright: MAGIC Software Development, 2000-2002
     
    3536// Version 1:
    3637// ----------
    37 // fLength   major axis of ellipse
    38 // fWidth    minor axis
    39 // fDelta    angle of major axis wrt x-axis
    40 // fSize     total sum of pixels
    41 // fMeanX    x of center of ellipse
    42 // fMeanY    y of center of ellipse
     38// fLength   [mm]       major axis of ellipse
     39// fWidth    [mm]       minor axis
     40// fDelta    [rad]      angle of major axis with x-axis
     41//                      by definition the major axis is pointing into
     42//                      the hemisphere x>0, thus -pi/2 < delta < pi/2
     43// fSize     [#CerPhot] total sum of pixels
     44// fMeanX    [mm]       x of center of ellipse
     45// fMeanY    [mm]       y of center of ellipse
    4346//
    4447// Version 2:
     
    9194// --------------------------------------------------------------------------
    9295//
     96// Initializes the values with defaults. For the default values see the
     97// source code.
     98//
    9399void MHillas::Reset()
    94100{
    95     fLength = 0;
    96     fWidth  = 0;
    97     fDelta  = 0;
     101    fLength = -1;
     102    fWidth  = -1;
     103    fDelta  =  0;
    98104
    99105    fSize   = -1;
     
    122128    *fLog << " - Length   [mm]  = " << fLength << endl;
    123129    *fLog << " - Width    [mm]  = " << fWidth  << endl;
     130    *fLog << " - Delta    [deg] = " << fDelta*kRad2Deg << endl;
     131    *fLog << " - Size     [1]   = " << fSize   << " #CherPhot"   << endl;
    124132    *fLog << " - Meanx    [mm]  = " << fMeanX  << endl;
    125133    *fLog << " - Meany    [mm]  = " << fMeanY  << endl;
    126     *fLog << " - Delta    [deg] = " << fDelta*kRad2Deg << endl;
    127134    *fLog << " - atg(y/x) [deg] = " << atg     << endl;
    128     *fLog << " - Size     [1]   = " << fSize   << " #CherPhot"   << endl;
    129135}
    130136
     
    207213// Calculate the image parameters from a Cherenkov photon event
    208214// assuming Cher.photons/pixel and pixel coordinates are given
     215// In case you don't call Calc from within an eventloop make sure, that
     216// you call the Reset member function before.
    209217//
    210218Bool_t MHillas::Calc(const MGeomCam &geom, const MCerPhotEvt &evt)
    211219{
    212     // FIXME: MHillas::Calc is rather slow at the moment because it loops
    213     //    unnecessarily over all pixels in all its loops (s.MImgCleanStd)
    214     //    The speed could be improved very much by using Hash-Tables
    215     //    (linked lists, see THashTable and THashList, too)
    216     //
    217 
    218220    const UInt_t npixevt = evt.GetNumPixels();
    219221
     
    222224    //
    223225    if (npixevt <= 2)
     226    {
     227        *fLog << warn << "MHillas::Calc: Event has less than two pixels... skipped." << endl;
    224228        return kFALSE;
     229    }
    225230
    226231    //
    227232    // calculate mean value of pixel coordinates and fSize
    228233    // -----------------------------------------------------
     234    //
     235    // Because this are only simple sums of roughly 600 values
     236    // with an accuracy less than three digits there should not
     237    // be any need to use double precision (Double_t) for the
     238    // calculation of fMeanX, fMeanY and fSize.
    229239    //
    230240    fMeanX = 0;
     
    235245    fNumCorePixels = 0;
    236246
    237     //
    238     // FIXME! npix should be retrieved from MCerPhotEvt
    239     //
    240247    for (UInt_t i=0; i<npixevt; i++)
    241248    {
     
    247254        const MGeomPix &gpix = geom[pix.GetPixId()];
    248255
    249         const float nphot = pix.GetNumPhotons();
     256        const Float_t nphot = pix.GetNumPhotons();
     257
     258        if (nphot==0)
     259            *fLog << warn << GetDescriptor() << ": Pixel #" << pix.GetPixId() << " has no photons." << endl;
    250260
    251261        fSize  += nphot;                             // [counter]
     
    260270
    261271    //
    262     // sanity check
    263     //
    264     if (fSize==0 || fNumUsedPixels<=2)
     272    // sanity checks
     273    //
     274    if (fSize==0)
     275    {
     276        *fLog << warn << GetDescriptor() << ": Event has zero cerenkov photons... skipped." << endl;
    265277        return kFALSE;
     278    }
     279
     280    if (fNumUsedPixels<3)
     281    {
     282        *fLog << warn << GetDescriptor() << ": Event has less than 3 used pixels... skipped." << endl;
     283        return kFALSE;
     284    }
    266285
    267286    fMeanX /= fSize;                                 // [mm]
     
    270289    //
    271290    // calculate 2nd moments
    272     // -------------------
    273     //
    274     float corrxx=0;                                  // [m^2]
    275     float corrxy=0;                                  // [m^2]
    276     float corryy=0;                                  // [m^2]
     291    // ---------------------
     292    //
     293    // To make sure that the more complicated sum is evaluated as
     294    // accurate as possible (because it is needed for more
     295    // complicated calculations (see below) we calculate it using
     296    // double prcision.
     297    //
     298    Double_t corrxx=0;                               // [m^2]
     299    Double_t corrxy=0;                               // [m^2]
     300    Double_t corryy=0;                               // [m^2]
    277301
    278302    for (UInt_t i=0; i<npixevt; i++)
     
    284308
    285309        const MGeomPix &gpix = geom[pix.GetPixId()];
    286         const float dx = gpix.GetX() - fMeanX;       // [mm]
    287         const float dy = gpix.GetY() - fMeanY;       // [mm]
    288 
    289         const float nphot = pix.GetNumPhotons();     // [#phot]
     310
     311        const Float_t dx = gpix.GetX() - fMeanX;     // [mm]
     312        const Float_t dy = gpix.GetY() - fMeanY;     // [mm]
     313
     314        const Float_t nphot = pix.GetNumPhotons();   // [#phot]
    290315
    291316        corrxx += nphot * dx*dx;                     // [mm^2]
     
    295320
    296321    //
     322    // If corrxy=0 (which should never happen, because fSize>0) we
     323    // cannot calculate Length and Width. The calculation failed
     324    // and returnes kFALSE
     325    //
     326    if (corrxy==0)
     327    {
     328        *fLog << warn << GetDescriptor() << ": Event has CorrXY==0... skipped." << endl;
     329        return kFALSE;
     330    }
     331
     332    //
    297333    // calculate the basic Hillas parameters: orientation and size of axes
    298334    // -------------------------------------------------------------------
    299335    //
    300     const float d = (corryy - corrxx)/(corrxy*2);
    301 
    302     fDelta = atan(d + sqrt(d*d + 1));
    303 
    304     fCosDelta = cos(fDelta);   // need these in derived classes
    305     fSinDelta = sin(fDelta);   // like MHillasExt
    306 
    307     float axis1 = ( fCosDelta*fSinDelta*corrxy*2 + fCosDelta*fCosDelta*corrxx + fSinDelta*fSinDelta*corryy) / fSize; // [mm^2]
    308     float axis2 = (-fCosDelta*fSinDelta*corrxy*2 + fSinDelta*fSinDelta*corrxx + fCosDelta*fCosDelta*corryy) / fSize; // [mm^2]
    309  
     336    // fDelta is the angle between the major axis of the ellipse and
     337    //  the x axis. It is independent of the position of the ellipse
     338    //  in the camera it has values between -pi/2 and pi/2 degrees
     339    //
     340    const Double_t d0   = corryy - corrxx;
     341    const Double_t d1   = corrxy*2;
     342    const Double_t d2   = d0 + sqrt(d0*d0 + d1*d1);
     343    const Double_t tand = d2 / d1;
     344
     345    fDelta = atan(tand);
     346
     347    const Double_t s2 = tand*tand+1;
     348    const Double_t s  = sqrt(s2);
     349
     350    fCosDelta =  1.0/s;   // need these in derived classes
     351    fSinDelta = tand/s;   // like MHillasExt
     352
     353    Double_t axis1 = (tand*tand*corryy + d2 + corrxx)/s2/fSize;
     354    Double_t axis2 = (tand*tand*corrxx - d2 + corryy)/s2/fSize;
     355
     356    //
     357    // fLength^2 is the second moment along the major axis of the ellipse
     358    // fWidth^2  is the second moment along the minor axis of the ellipse
     359    //
     360    // From the algorithm we get: fWidth <= fLength is always true
     361    //
    310362    // very small numbers can get negative by rounding
    311     if (axis1 < 0) axis1=0;
    312     if (axis2 < 0) axis2=0;
    313 
    314     fLength = sqrt(axis1);  // [mm]
    315     fWidth  = sqrt(axis2);  // [mm]
     363    //
     364    fLength = axis1<0 ? 0 : sqrt(axis1);  // [mm]
     365    fWidth  = axis2<0 ? 0 : sqrt(axis2);  // [mm]
    316366
    317367    SetReadyToSave();
     
    322372// --------------------------------------------------------------------------
    323373//
     374/*
    324375void MHillas::AsciiRead(ifstream &fin)
    325376{
     
    331382    fin >> fMeanY;
    332383}
    333 
     384*/
    334385// --------------------------------------------------------------------------
    335386/*
Note: See TracChangeset for help on using the changeset viewer.