Ignore:
Timestamp:
11/18/02 10:46:48 (22 years ago)
Author:
tbretz
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/mhist/MHArray.cc

    r1576 r1629  
    3737//  by its index.
    3838//
    39 //  To map a key to the index use/see MFillH, which automatically maps a
    40 //  key-value to the array index.
     39//  To access the histograms by a key instead of an index use SetIndexByKey
     40//  instead of Set/Inc/DecIndex. It will take the integerpart of the
     41//  floating point value (2 in case of 2.9). For each new key a new
     42//  index in the Mapping Table is created. So that you can access your
     43//  histograms by the key (eg in case of the Angle Theta=23.2deg use
     44//  SetIndexByKey(23.2)
     45//
     46//  If the index is equal to the number of histograms in the array a call
     47//  to the Fill-member-function will create a new histogram.
    4148//
    4249//  In the constructor istempl leads to two different behaviours of the
     
    7380ClassImp(MHArray);
    7481
    75 // --------------------------------------------------------------------------
    76 //
    77 // Default Constructor. hname is the name of the histogram class which
    78 // is in the array.
     82//////////////////////////////////////////////////////////////////////////////
     83//
     84// MMap
     85//
     86// This class maps a key-value to a given value. In its simple versions it
     87// maps a key to an index.
     88//
     89//////////////////////////////////////////////////////////////////////////////
     90#include <TArrayI.h>
     91
     92class MMap
     93{
     94private:
     95    TArrayI fKeys;
     96    TArrayI fValues;
     97
     98    Int_t K(Int_t i) const { return ((TArrayI)fKeys)[i]; }
     99    Int_t V(Int_t i) const { return ((TArrayI)fValues)[i]; }
     100
     101public:
     102    // --------------------------------------------------------------------------
     103    //
     104    // Return the size of the table
     105    //
     106    Int_t GetSize() const
     107    {
     108        return fKeys.GetSize();
     109    }
     110
     111    // --------------------------------------------------------------------------
     112    //
     113    // Get the value which corresponds to the given key-value
     114    //
     115    Int_t GetValue(Int_t key) const
     116    {
     117        const Int_t n = fKeys.GetSize();
     118        for (int i=0; i<n; i++)
     119        {
     120            if (K(i)==key)
     121                return V(i);
     122        }
     123        return -1;
     124    }
     125
     126    // --------------------------------------------------------------------------
     127    //
     128    // Get the key which corresponds to the given index
     129    //
     130    Int_t GetKey(Int_t value) const
     131    {
     132        const Int_t n = fKeys.GetSize();
     133        for (int i=0; i<n; i++)
     134        {
     135            if (V(i)==value)
     136                return K(i);
     137        }
     138        return -1;
     139    }
     140
     141    // --------------------------------------------------------------------------
     142    //
     143    // Adds a new pair key-value. While the key is the key to the value.
     144    // if the key already exists the pair is ignored.
     145    //
     146    void Add(Int_t key, Int_t value)
     147    {
     148        if (GetValue(key)>=0)
     149            return;
     150
     151        const Int_t n = fKeys.GetSize();
     152
     153        fKeys.Set(n+1);
     154        fValues.Set(n+1);
     155
     156        fKeys[n] = key;
     157        fValues[n] = value;
     158    }
     159
     160    // --------------------------------------------------------------------------
     161    //
     162    // Adds a new pair key-value. While the key is the key to the value.
     163    // In this case the value is an automatically sequential created index.
     164    // if the key already exists the pair is ignored.
     165    //
     166    Int_t Add(Int_t key)
     167    {
     168        const Int_t k = GetValue(key);
     169        if (k>=0)
     170            return k;
     171
     172        const Int_t n = fKeys.GetSize();
     173
     174        fKeys.Set(n+1);
     175        fValues.Set(n+1);
     176
     177        fKeys[n] = key;
     178        fValues[n] = n;
     179
     180        return n;
     181    }
     182};
     183
     184// --------------------------------------------------------------------------
     185//
     186// hname is the name of the histogram class which is in the array.
    79187//
    80188// istempl=kTRUE tells MHArray to use the first histogram retrieved from the
     
    95203    fTitle = title ? TString(title) : (TString("Base class for Mars histogram arrays:") + hname);
    96204
     205    fMapIdx = new MMap;
     206
    97207    fArray = new TList;
    98208    fArray->SetOwner();
     
    131241// --------------------------------------------------------------------------
    132242//
     243// Default Constructor. hname is the name of the histogram class which
     244// is in the array.
     245//
     246// istempl=kTRUE tells MHArray to use the first histogram retrieved from the
     247// ParameterList by hname to be used as a template. New histograms are not
     248// created using the root dictionary, but the New-member function (see
     249// MParConatiner)
     250// In the case istempl=kFALSE new histograms are created using the root
     251// dictionary while hname is the class name. For the creation their
     252// default constructor is used.
     253//
     254MHArray::MHArray(const MH *hist, const char *name, const char *title)
     255    : fIdx(0), fClass(NULL), fTemplate(hist), fTemplateName("<dummy>")
     256{
     257    //
     258    //   set the name and title of this object
     259    //
     260    fName  = name  ? name  : "MHArray";
     261    fTitle = title ? TString(title) : (TString("Base class for Mars histogram arrays:") + hist->GetName());
     262
     263    fMapIdx = new MMap;
     264
     265    fArray = new TList;
     266    fArray->SetOwner();
     267}
     268
     269// --------------------------------------------------------------------------
     270//
    133271// Destructor: Deleteing the array and all histograms which are part of the
    134272// array.
     
    138276    fArray->Delete();
    139277    delete fArray;
    140 }
    141 
    142 
     278    delete fMapIdx;
     279}
     280
     281// --------------------------------------------------------------------------
     282//
     283//  Use this to access the histograms by a key. If you use values like
     284//   (in this order) 2.5, 7.2, 2.5, 9.3, 9.3, 3.3, 2.2, 1.1
     285//  it will be mapped to the following indices internally:
     286//                    0    1    0    2    2    3    4    5
     287//
     288//  WARNING: Make sure that you don't create new histograms by setting
     289//           a new index (SetIndex or IncIndex) which is equal the size
     290//           of the array and create new histogram by CreateH. In this
     291//           case you will confuse the mapping completely.
     292//
     293void MHArray::SetIndexByKey(Double_t key)
     294{
     295    fIdx = fMapIdx->Add((Int_t)key);
     296}
     297
     298// --------------------------------------------------------------------------
     299//
     300//  Use this function to access a histogram by its index in the array.
     301//  Becarefull the index isn't checked!
     302//
    143303MH &MHArray::operator[](Int_t i)
    144304{
     
    146306}
    147307
     308// --------------------------------------------------------------------------
     309//
     310//  Use this function to access a histogram by its index in the array.
     311//  Becarefull the index isn't checked!
     312//
    148313MH *MHArray::At(Int_t i)
    149314{
     
    151316}
    152317
     318// --------------------------------------------------------------------------
     319//
     320//  Use this function to access the histogram corresponding to the
     321//  currently set index (by Set/Inc/DecIndex or SetIndexByKey)
     322//  Becarefull the index set isn't checked!
     323//
    153324MH *MHArray::GetH()
    154325{
     
    170341    if (fTemplate)
    171342    {
     343        //
     344        // create the parameter container as a clone of the existing
     345        // template histogram.
     346        //
    172347        hist = (MH*)fTemplate->New();
    173348    }
     
    226401    fIdx = 0;
    227402
     403    if (fTemplate)
     404        return kTRUE;
     405
    228406    if (!fTemplateName.IsNull())
    229407    {
     
    246424    const Int_t n = fArray->GetSize();
    247425
    248     if (fIdx <0 || fIdx>n)
     426    if (fIdx<0 || fIdx>n)
    249427    {
    250428        *fLog << warn << "Histogram Index #" << fIdx << " out of bounds (>";
     
    287465    *fLog << all << GetDescriptor() << " contains " << fArray->GetSize();
    288466    *fLog << " histograms." << endl;
    289 }
     467
     468    if (fMapIdx->GetSize()<=0)
     469        return;
     470
     471    *fLog << " idx\t     key" << endl;
     472    for (int i=0; i<fMapIdx->GetSize(); i++)
     473        *fLog << "  " << i << "\t<-->  " << fMapIdx->GetKey(i) << endl;
     474    *fLog << endl;
     475}
     476
     477// --------------------------------------------------------------------------
     478//
     479// Adds the given object to the given legend (if != NULL). The Legend
     480// entry name is created from the key...
     481//
     482void MHArray::AddLegendEntry(TLegend *leg, TObject *obj, Int_t idx) const
     483{
     484    if (!leg)
     485        return;
     486
     487    TString name = " ";
     488    name += fMapIdx->GetKey(idx);
     489    leg->AddEntry(obj, name, "lpf"); // l=line, p=polymarker, f=fill
     490}
     491
    290492
    291493// --------------------------------------------------------------------------
     
    302504    gStyle->SetOptStat(0);
    303505
     506    //
     507    // if the keymapping is used create a legend to identify the histograms
     508    //
     509    TLegend *leg = NULL;
     510    if (fMapIdx->GetSize()>0)
     511    {
     512        leg = new TLegend(0.85, 0.80, 0.99, 0.99);
     513        leg->SetBit(kCanDelete);
     514    }
     515
    304516    TIter Next(fArray);
    305517    MH *hist = (MH*)Next();
    306518
    307     Int_t col=2;
     519    Int_t idx=0;
    308520    Double_t max=0;
    309521    Double_t min=0;
     
    311523    TH1 *h1=NULL;
    312524
     525    //
     526    // If the array has at least one entry:
     527    //  - find the starting boundaries
     528    //  - draw it and set its line color
     529    //
    313530    if (hist)
    314531    {
     
    316533        {
    317534            h1->Draw();
    318             h1->SetLineColor(col++);
     535            h1->SetLineColor(idx+2);
    319536            max = h1->GetMaximum();
    320537            min = h1->GetMinimum();
     538
     539            AddLegendEntry(leg, h1, idx);
    321540        }
    322541    }
    323542
     543    //
     544    // For all following histograms:
     545    //  - update the boundaries
     546    //  - draw it and set its line color
     547    //
    324548    while ((hist=(MH*)Next()))
    325549    {
     
    330554
    331555        h->Draw("same");
    332         h->SetLineColor(col++);
     556        h->SetLineColor(idx+2);
    333557        if (max<h->GetMaximum())
    334558            max = h->GetMaximum();
    335559        if (min>h->GetMinimum())
    336560            min = h->GetMinimum();
    337     }
    338 
     561
     562        AddLegendEntry(leg, h, idx++);
     563    }
     564
     565    //
     566    // Now update the drawing region so that everything is displayed
     567    //
    339568    if (h1)
    340569    {
     
    342571        h1->SetMaximum(max>0 ? max*1.05 : max*0.95);
    343572    }
     573
     574    if (leg)
     575        leg->Draw();
     576
    344577    gPad->Modified();
    345578    gPad->Update();
     
    353586// the MH entries by calling their GetHistByName function.
    354587// If the option also contains 'nonew' no new canvas is created.
     588// The option "Scale=1" scales the area of all histogram to 1
     589// The option "Scale=max" scales the maximum of all histogram to 1
    355590//
    356591TObject *MHArray::DrawClone(Option_t *opt) const
     
    360595    TCanvas *c = NULL;
    361596
    362     Int_t nonew = o.Index("nonew", TString::kIgnoreCase);
     597    Int_t scale1   = o.Index("scale=1",   TString::kIgnoreCase);
     598    Int_t scalemax = o.Index("scale=max", TString::kIgnoreCase);
     599    Int_t nonew    = o.Index("nonew",     TString::kIgnoreCase);
     600
     601    if (o.BeginsWith("scale=1", TString::kIgnoreCase))
     602        scale1 = 0;
     603    if (o.BeginsWith("scale=max", TString::kIgnoreCase))
     604        scalemax = 0;
     605    if (o.BeginsWith("nonew", TString::kIgnoreCase))
     606        nonew = 0;
     607
    363608    if (nonew>=0)
    364609    {
     
    372617        o.Remove(nonew, 5);
    373618    }
     619    if (scale1>=0)
     620        o.Remove(scale1, 7);
     621    if (scalemax>=0)
     622        o.Remove(scalemax, 9);
    374623
    375624    const Stat_t sstyle = gStyle->GetOptStat();
    376625    gStyle->SetOptStat(0);
    377626
     627    //
     628    // if the keymapping is used create a legend to identify the histograms
     629    //
     630    TLegend *leg = NULL;
     631    if (fMapIdx->GetSize()>0)
     632    {
     633        leg = new TLegend(0.85, 0.80, 0.99, 0.99);
     634        leg->SetBit(kCanDelete);
     635    }
     636
    378637    TIter Next(fArray);
    379638    MH *hist = (MH*)Next();
    380639
    381     Int_t col=2;
     640    Int_t idx=0;
    382641    Double_t max=0;
    383642    Double_t min=0;
     
    385644    TH1 *h1=NULL;
    386645
     646     //
     647    // If the array has at least one entry:
     648    //  - find the starting boundaries
     649    //  - draw it and set its line color
     650    //
    387651    if (hist)
    388652    {
     
    390654        {
    391655            h1 = (TH1*)h1->DrawCopy();
    392             h1->SetMarkerColor(col);
    393             h1->SetLineColor(col++);
     656
     657            if (scale1>=0)
     658                h1->Scale(1./h1->Integral());
     659            if (scalemax>=0)
     660                h1->Scale(1./h1->GetMaximum());
     661
     662            h1->SetMarkerColor(idx);
     663            h1->SetLineColor(idx+2);
    394664            h1->SetFillStyle(4000);
    395665            max = h1->GetMaximum();
    396666            min = h1->GetMinimum();
     667
     668            AddLegendEntry(leg, h1, idx++);
    397669        }
    398670    }
    399671
     672    //
     673    // For all following histograms:
     674    //  - update the boundaries
     675    //  - draw it and set its line color
     676    //
    400677    while ((hist=(MH*)Next()))
    401678    {
     
    406683
    407684        h = (TH1*)h->DrawCopy("same");
    408         h->SetMarkerColor(col);
    409         h->SetLineColor(col++);
    410         h->SetFillStyle(4000);
     685
     686        if (scale1>=0)
     687            h->Scale(1./h->Integral());
     688        if (scalemax>=0)
     689            h->Scale(1./h->GetMaximum());
     690
     691        h->SetMarkerColor(idx);
     692        h->SetLineColor(idx+2);
     693        h->SetFillStyle(4000); // transperent (why is this necessary?)
    411694        if (max<h->GetMaximum())
    412695            max = h->GetMaximum();
    413696        if (min>h->GetMinimum())
    414697            min = h->GetMinimum();
    415     }
    416 
     698
     699        AddLegendEntry(leg, h, idx++);
     700    }
     701
     702    //
     703    // Now update the drawing region so that everything is displayed
     704    //
    417705    if (h1)
    418706    {
     
    420708        h1->SetMaximum(max>0 ? max*1.05 : max*0.95);
    421709    }
     710
     711    if (leg)
     712        leg->Draw();
     713
    422714    gPad->Modified();
    423715    gPad->Update();
Note: See TracChangeset for help on using the changeset viewer.