/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 12/2000 (tbretz@uni-sw.gwdg.de) ! ! Copyright: MAGIC Software Development, 2000-2001 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // // MParList // // // // This class contains a list of different parameter containers. // // // // A parameter container is an object which is derived from // // MParContainer. // // // // Normally a parameter container is used for data exchange between two // // tasks at runtime. // // // // You can add every parameter container (Named object) to the // // instance and access it from somewhere else via its Name. // // // ///////////////////////////////////////////////////////////////////////////// #include "MParList.h" #include #include #include #include "MLog.h" #include "MLogManip.h" ClassImp(MParList); // -------------------------------------------------------------------------- // // default constructor // creates an empty list // MParList::MParList(const char *name, const char *title) { *fName = name ? name : "MParList"; *fTitle = title ? title : "A list of Parameter Containers"; // // This sets a flag that the list is the owner, which means // that the destructor of the list deletes all it's objects // fAutodelete.SetOwner(); } // -------------------------------------------------------------------------- // // Copy constructor. It copies all entries of the parameter list, but it // takes care of, that the automatically created entries are only deleted // once. (doesn't copy the list which holds the automatically created // entries) // MParList::MParList(MParList &ts) { fContainer.AddAll(&ts.fContainer); } // -------------------------------------------------------------------------- // // If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted // by the destructor // MParList::~MParList() { if (TestBit(kIsOwner)) fContainer.SetOwner(); } // -------------------------------------------------------------------------- // // If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted // by the destructor // inline void MParList::SetOwner(Bool_t enable=kTRUE) { enable ? SetBit(kIsOwner) : ResetBit(kIsOwner); } // -------------------------------------------------------------------------- // // Set the logging streamer of the parameter list and all contained // parameter containers // void MParList::SetLogStream(MLog *log) { TIter Next(&fContainer); MParContainer *cont=NULL; // // loop over all tasks for preproccesing // while ( (cont=(MParContainer*)Next()) ) cont->SetLogStream(log); MParContainer::SetLogStream(log); } // -------------------------------------------------------------------------- // // Add a single container to the list. // // If 'where' is given, the object will be added after this. // Bool_t MParList::AddToList(MParContainer *cont, MParContainer *where) { // // check if the object (you want to add) exists // if (!cont) return kFALSE; // // Get Name of new container // const char *name = cont->GetName(); // // Check if the new container is already existing in the list // const TObject *objn = fContainer.FindObject(name); const TObject *objt = fContainer.FindObject(cont); if (objn || objt) { // // If the container is already in the list ignore it. // if (objt || objn==cont) { *fLog << dbginf << "Warning: Container '" << cont->GetName() << ", 0x" << (void*)cont; *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl; return kTRUE; } // // Otherwise add it to the list, but print a warning message // *fLog << dbginf << "Warning: Container with the same name '" << cont->GetName(); *fLog << "' already existing in '" << GetName() << "'." << endl; *fLog << "You may not be able to get a pointer to container task by name." << endl; } // // check if you want to add the new parameter container somewhere // special (in that case you specify "where") // if (where) { if (!fContainer.FindObject(where)) { *fLog << dbginf << "Error: Cannot find parameter container after which the new one should be added!" << endl; return kFALSE; } } *fLog << "Adding " << name << " to " << GetName() << "... " << flush; fContainer.Add(cont); *fLog << "Done." << endl; return kTRUE; } // -------------------------------------------------------------------------- // // Add all entries of the TObjArray to the list. // void MParList::AddToList(TObjArray *list) { // // check if the object (you want to add) exists // if (!list) return; TObjArrayIter Next(list); MParContainer *cont = NULL; while ((cont=(MParContainer*)Next())) { // // Get Name of new container // const char *name = cont->GetName(); // // Check if the new container is already existing in the list // const TObject *objn = fContainer.FindObject(name); const TObject *objt = fContainer.FindObject(cont); if (objn || objt) { // // If the container is already in the list ignore it. // if (objt || objn==cont) { *fLog << dbginf << "Warning: Container '" << cont->GetName() << ", 0x" << (void*)cont; *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl; continue; } // // Otherwise add it to the list, but print a warning message // *fLog << dbginf << "Warning: Container with the same name '" << cont->GetName(); *fLog << "' already existing in '" << GetName() << "'." << endl; *fLog << "You may not be able to get a pointer to container task by name." << endl; } *fLog << "Adding " << name << " to " << GetName() << "... " << flush; fContainer.Add(cont); *fLog << "Done." << endl; } } // -------------------------------------------------------------------------- // // Find an object in the list. // 'name' is the name of the object you are searching for. // TObject *MParList::FindObject(const char *name) const { return fContainer.FindObject(name); } // -------------------------------------------------------------------------- // // check if the object is in the list or not // TObject *MParList::FindObject(TObject *obj) const { return fContainer.FindObject(obj); } // -------------------------------------------------------------------------- // // returns the ClassName without anything which is behind that last ';' in // string. // TString MParList::GetClassName(const char *classname) { TString cname(classname); const char *semicolon = strrchr(cname, ';'); if (semicolon) cname.Remove(semicolon-cname); return cname; } // -------------------------------------------------------------------------- // // returns the ObjectName. It is created from a class and object name. // If no object name is given the objectname is the same than the // class name. Leading dots are removed from the object name // TString MParList::GetObjectName(const char *classname, const char *objname) { TString cname(classname); const char *semicolon = strrchr(cname, ';'); TString oname(objname ? objname : classname); if (semicolon) { // // Remove leading dots from objectname (eg. "MMcTrig;5.") // Int_t sz = oname.Sizeof()-2; while (sz>=0 && oname[sz]=='.') oname.Remove(sz--); } return oname; } // -------------------------------------------------------------------------- // // Find an object in the list. // 'name' is the name of the object you are searching for. // If the object doesn't exist we try to create one from the // dictionary. If this isn't possible NULL is returned. // // An object which was created automatically is deleted automatically in // the destructor of the parameter list, too. This means, that if an // object should survive (eg. Histograms) you MUST create it by yourself // and add it to the parameter list. // // By default (you don't specify an object name) the object name is // the same as the classname // // If the classname (default classname) is of the structure // "Name;something" - containing a semicolon - evarything which is // after the last appearance of a semicolon is stripped to get the // Name of the Class. Normally this is used to number your objects. // "Name;1", "Name;2", ... If a semicolon is detected leading dots // are stripped from the object-name (eg. "name;5.") // MParContainer *MParList::FindCreateObj(const char *classname, const char *objname) { // // If now object name (name of the object to identify it in the // List) is given use it's classname as the objectname // // // Check if the classname is a 'numbered' name (like: "MTime;2") // if so strip the number from the classname. // // Becareful: We check for the last occurance of a ';' only and we // also don't check if a number follows or something else. // // Rem: I use a TString to make the code more readyble and to get // the new object deleted automatically // TString cname = GetClassName(classname); TString oname = GetObjectName(classname, objname); // // Try to find a object with this object name which is already // in the List. If we can find one we are done. // MParContainer *pcont = (MParContainer*)FindObject(oname); if (pcont) return pcont; // // if object is not existing in the list try to create one // *fLog << dbginf << "Object '" << oname << "' of type '" << cname << "' not found... creating." << endl; // // try to get class from root environment // TClass *cls = gROOT->GetClass(cname); if (!cls) { // // if class is not existing in the root environment // *fLog << dbginf << "Class '" << cname << "' not existing in dictionary." << endl; return NULL; } // // create the parameter container of the the given class type // pcont = (MParContainer*)cls->New(); // // Set the name of the container // pcont->SetName(oname); // // Now add the object to the parameter list // AddToList(pcont); // // The object was automatically created. This makes sure, that such an // object is deleted together with the list // fAutodelete.Add(pcont); // // Find an object in the list. // 'name' is the name of the object you are searching for. // return pcont; } // -------------------------------------------------------------------------- // // print some information about the current status of MParList // void MParList::Print(Option_t *t) { *fLog << dbginf << "ParList: " << this->GetName() << " <" << this->GetTitle() << ">" << endl; *fLog << endl; } // -------------------------------------------------------------------------- // // Sets the flags off all containers in the list (and the list // itself) to unchanged // void MParList::SetReadyToSave(Bool_t flag) { TIter Next(&fContainer); MParContainer *cont=NULL; // // loop over all tasks for preproccesing // while ( (cont=(MParContainer*)Next()) ) cont->SetReadyToSave(flag); MParContainer::SetReadyToSave(flag); } // -------------------------------------------------------------------------- // // Reset all containers in the list // void MParList::Reset() { TIter Next(&fContainer); MParContainer *cont=NULL; // // loop over all tasks for preproccesing // while ((cont=(MParContainer*)Next())) cont->Reset(); } // -------------------------------------------------------------------------- // // This finds numbered objects. The objects are returned in a copy of a // TObjArray. // // If from only is given (or to=0) object are assumed numbered // from 1 to from. // TObjArray MParList::FindObjectList(const char *name, const UInt_t from, const UInt_t to) const { TObjArray list; if (to>0 && to<=from) { *fLog << dbginf << "Cannot create entries backwards (to0 && to==0; const UInt_t first = exc ? 0 : from; const UInt_t last = exc ? from : to; for (UInt_t num=first; num0 && to<=from) { *fLog << dbginf << "Cannot create entries backwards (to0 && to==0; const UInt_t first = exc ? 0 : from; const UInt_t last = exc ? from : to; for (UInt_t num=first; numGetClass(cname); if (!cls) { // // if class is not existing in the root environment // gLog << dbginf << "Class '" << cname << "' not existing in dictionary." << endl; return list; } const UInt_t len = strlen(cname); char *auxname = new char[len+7]; strcpy(auxname, cname); // // If only 'from' is specified the number of entries are ment // const Bool_t exc = from>0 && to==0; const UInt_t first = exc ? 0 : from; const UInt_t last = exc ? from : to; for (UInt_t num=first; numNew(); // // Set the name of the container // pcont->SetName(auxname); // // Add new object to the return list // list.AddLast(pcont); } delete auxname; return list; }