Fermilab


MINOS Offline Documentation
[home] [installing MINOS software] [supported platforms] [package links] [mailing list] [HyperNews] [FAQ] [computing help] [MINOS glossary] [archives]

Using and Updating the MINOS Software




Note: if you have yet to install the MINOS software then please follow the installation instructions for either msrt or install_minossoft


Creating a test release for doing code development

When you want to develop code in a package, you do this in a so called "test" release. This is a release which is in your own area but is supported by the "base" release which is either the "development" or one of the "frozen" releases. Be warned that developing against a frozen release can lead to problems when porting it to the latest development release. In general, it is best to have your test releases based on the development release.

The following assumes that your environment is setup to use the "development" base release.

  1. Choose a location for you test release. You may have multiple test releases.
        shell> cd </path/tosome/dir>
    

  2. Create an empty test release based on the "development" base:
        shell> newrel -t development test
    
    This will create a directory called "test" which contains a main GNUmakefile and empty sub-directories bin, doc, include, etc. The -t option indicates that this is a test release and not a base release.

  3. Enter the new "test" directory and set up your SRT environment to use this test release.
        shell> cd test
        shell> srt_setup -a
    
    When compiling code or running executables, any libraries or executables will be looked for in this "test" release before being looked for in the associated base release.



Adding Packages to Modify to a Test Release

There are two ways to add a package into a test release. One way will check out a copy of the source code and the other will just create a symlink to the package in the base release. You use the former if you want to modify the code and the latter If you don't.

As an example consider if we want to modify the Algorithm package. (Note: this is a framework package and it is unlikely a user would actually need or want to modify it).

  1. Check out the package to modify from the repository
        shell> addpkg -h Algorithm
    
    This will check out the most recent (or "HEAD") version of the package into and create a symlink in the include/ directory to this package directory.

  2. You can now modify any files in this package. Fix some bugs, add some features (add some bugs). Play around, have fun.

  3. To build the package you can either run "make" in the package directory, or from the top level by doing:
        shell> gmake Algorithm.all
    
    See also this page for ways to speed up building your test release.

  4. Libraries and object files for the package can be removed by running "make clean" in the package directory or from the top level by doing:
        shell> gmake Algorithm.clean
    
    Running "make clean" on at the top level will clean the libraries and object files from all packages.

  5. If you have changed any of the packages header files, then you must check that any other packages that depend on this one are not adversely effected. Do do this, follow these steps:

    1. First find out what package depend on the one you modified with SRT's depend command:
          shell> depend Algorithm
          Looking in release development...
          These packages in release development use \
          include files from package Algorithm:
          Algorithm
          BubbleSpeak
          CandClusterSR
          CandDigit
          CandEvent
          CandEventSR
          CandFitTrackSR
          CandShowerSR
          CandSliceSR
          CandStripSR
          CandTrackSR
          CandVtx
          Candidate
          DeMux
          DynamicFactory
      
      Note: the output may look different depending on what dependent packages exist in the base release.

    2. Add all these packages to your "test" release. Because you probably don't need to actually modify any of these dependent packages we only symlink them using lnkpkg instead of adding them proper like we did with the original package:
          shell> lnkpkg BubbleSpeak
          shell> lnkpkg CandClusterSR
          shell> lnkpkg CandDigit
          shell> lnkpkg CandEvent
          shell> lnkpkg CandEventSR
          shell> lnkpkg CandFitTrackSR
          shell> lnkpkg CandShowerSR
          shell> lnkpkg CandSliceSR
          shell> lnkpkg CandStripSR
          shell> lnkpkg CandTrackSR
          shell> lnkpkg CandVtx
          shell> lnkpkg Candidate
          shell> lnkpkg DeMux
          shell> lnkpkg DynamicFactory
    3. Now, rebuild all these packages
          shell> cd test
          shell> gmake all
      
      This will invoke GNU make and build the libraries and any executables that may be defined (note that test executables are not built by default, they must be built by gmake tbin). All other libraries and header files that were not included by doing lnkpkg will be taken from the base release.

    4. Any packages failing to build because of changes to the original package's header files will need to be fixed. To do this you need to check out a copy that can be modified. For example, assume BubbleSpeak needed fixing, you would do:
          shell> rmpkg BubbleSpeak
          shell> addpkg -h BubbleSpeak
      



Getting Build Information

There are a few things to help you get information about the building of your packages:
  • You can see internal SRT makefile variables by doing:
        shell> gmake echo_<VARIABLE>
    
    or
        shell> gmake Algorithm.echo_<VARIABLE>
    
    The VARIABLE you are most likely to want to see is CPPFLAGS.
  • Normally, SRT makefiles will not show much information. You can change this by setting the environment variable MINOS_VERBOSE, eg:
        tcsh> setenv MINOS_VERBOSE on
        bash> export MINOS_VERBOSE=on
    



Commiting Changes Back to the CVS Repository

When the user is happy with the changes they can commit them back to the CVS repository. See the section for developers in the MINOS Software Repository page.




Removing Packages from your Test Release

To remove a package from your test release use
    shell> cd $SRT_PRIVATE_CONTEXT
    shell> gmake mypackage.clean
    shell> rmpkg mypackage



Saving Disk Space (diverting lib, bin, and tmp to another disk)

If you have limited disk space in your home area then it is possible to divert the lib, bin and tmp areas to another disk. To do this create a file: $HOME/.srtrc which contains:
  extra_dirs="$extra_dirs \
              tmp>/data_02/lartey/tmp \
              bin>/data_02/lartey/bin \
              lib>/data_02/lartey/lib"
This file gets sourced when you run newrel to create your test release. It will make tmp, bin and lib appear as links to the directory you specified.


Creating a test release for a pserver base release

If your base release uses a read-only repository access method and you wish to commit any modifications to packages in your test release, you will have to explicitly tell addpkg to use the read-write access method. See the page on the MINOS Software Repository for information on gaining read-write access.

To explicitly use the read-write access method replace the calls to addpkg above with

    shell> addpkg -d minoscvs@minoscvs.fnal.gov:/cvs/minoscvs/rep1 <package> 

If you already used addpkg and have read-only access, you can change to read-write access with SRT's cvsmigrate script. For example:

 
    shell> cd <my-package-directory>
    shell> cvsmigrate -o \
	:pserver:anonymous@minoscvs.fnal.gov:/cvs/minoscvs/rep1 -d \
	minoscvs@minoscvs.fnal.gov:/cvs/minoscvs/rep1 
    shell> cvsmigrate --help for more info 
This will need to be done in package directory for which you want have read-write access.


Creating a test release for frozen release

The following assumes that you have the frozen base release, R<version> and you want to modify the package Algorithm within a test release called test. It assumes you have sourced the setup file described in the installation instructions.

    shell> cd <your_dir>
    shell> newrel -t R<x.y.z> test
This will create a directory called test under <your_dir> which contains a main GNUmakefile and empty sub-directories bin, doc, include etc. The -t option indicates that this is a user's test release and not an official release. The test release does not contain any packages yet.
    shell> cd test
    shell> srt_setup -a
This will set the local SRT context to the current test release. This means that the bin area of your test release will be put into your path before the base release for example.
    shell> addpkg -n Algorithm
This checks out the package Algorithm from the base release area and places it in the user's test release. Note that it is important to specify the -n option. Addpkg without the -n option or with -h option will checkout the code from CVS. It creates a soft link between the test release include area and the package. We will assume that the user wishes to modify some of the include files that are in the package Algorithm. These include files may be used by other packages and so in order for the user to fully test their changes they must rebuild all the packages that use the modified include files. However, they do not need to actually modify any of the other packages. To determine which packages depend on Algorithm use the depend command and carry the same procedure above as done for the developmental test release.




Tagging a test release for a frozen release

The convention for tagging a release is:
    shell> cvs rtag V<XX-YY-ZZ> <package> 
where ZZ indicates a bug fix release, YY is an API backward compatible release, and XX is a major release.




Removing a base release

If a user wants to remove a release.
  1.   prompt> cd $SRT_DIST/releases
  2.   rmrel R<x.y.z>




Creating a new package in a test release

Often the developer may wish to create a new package in their test release.
  1. After executing the three steps in Creating a test release for doing code development the user needs to
        shell> mkdir mypackage
  2.     shell> cd $SRT_PRIVATE_CONTEXT/include
  3.     shell> ln -s ../mypackage mypackage 
  4. Create the source and header files and a GNUmakefile for the package. An example of a simple GNUmakefile for a package that only builds a single library. Look at existing MINOS packages for more examples.
  5. When happy with the code, create a CVS module and check the code in. This allows other users to add your package to their test release.
  6. In order for a package to get added to the base release it must be listed in the packages-development file. Please contact Ed Tetteh-Lartey to get your package added once the offline group has agreed that it should be included.

Notes:

  • If your package includes test code then it should be placed in a test directory which should build a library containing the test code.
  • The test executables should be added to the tbin target and only get built if the user runs gmake tbin. Examples of GNUmakefiles for packages with test code can be found in the examples.
If you have root macros you can put them in the main package directory or in a macros directory. You need to make sure that the macros get moved to the releases/development/macros directory. There are examples of this on the examples page. If you get stuck then please send mail to lartey@fnal.gov.


Adding a new class in a test release

Here is an outline the steps to necessary create a new class showing how to incorporate the ROOT dictionary so that it can be written out.

  1. First create its header (MyClass.h):-
    #ifndef MYCLASS_H
    #define MYCLASS_H
    
    #include <string>
    #include "TObject.h"
    
    class MyClass : public TObject {
    
    public:
    
      MyClass(const char* name = "Anonymous") { fName = name; }
     ~MyClass() {}
      void SetName(const char* name) { fName = name; }
      void Speak() const;
    
    private:
    
      string fName;
    
    ClassDef(MyClass,1)     // Example class
    
    };
    
    #endif  // MYCLASS_H
    
    note the ClassDef which is a macro defined by ROOT to declare further members for your class.

  2. Next write its implementation file (MyClass.cxx):-
    #include <stdio.h>
    #include "mypackage/MyClass.h"
    
    ClassImp(MyClass)
    
    void MyClass::Speak() const {
      cout << "Hi, I am " <<  fName << endl; 
    }
    
    
    This time the ClassImp macro defines these new members.

  3. You will also need a LinkDef.h:-
    #ifdef __CINT__
    
    #pragma link off all globals;
    #pragma link off all classes;
    #pragma link off all functions;
    
    #pragma link C++ class MyClass+;
    
    #endif
    
    This is going to be used by ROOT's rootcint utility to define a dictionary for your class. The plus at the end of MyClass tells rootcint to use the new I/O system. That's what MINOS uses and it will eventually be the default.

  4. The last file is the GNUmakefile:-
    # Makefile for mypackage package
    
    # Define whether rootcint should be run to generate ROOT
    # dictionaries
    
    ROOTCINT:= YES
    
    # library
    LIB:= lib$(PACKAGE)
    
    #library contents
    LIBCXXFILES:= $(wildcard *.cxx)
    
    
    ########################################################################
    include SoftRelTools/standard.mk
    include SoftRelTools/arch_spec_root.mk
    
    This tells SRT that you want rootcint and the the library will take the default name, which as your package is called mypackage, will be libmypackage (.so for shareable) and consists of all the .cxx files in the directory.

  5. Now you are ready to build you library:-
      prompt> cd $SRT_PRIVATE_CONTEXT
      prompt> gmake mypackage.all
    
    which should produce output like this:-
    <**all**> mypackage
    Generating mypackageCint.cc dictionary...
    <**compiling**> MyClass.cxx
    <**compiling**> mypackageCint.cc
    <**building library**> libmypackage
    

  6. Now you can run ROOT and try to communicate with your object:-
     prompt> root -b
    
    First load the mypackage library:-
     root [0] gSystem.Load("libmypackage.so");
    
    if this fails then something is wrong with your LD_LIBRARY_PATH.

    Next try to create and talk to objects on the heap and the stack:-

     root [1] MyClass jim("Jim");
     root [2] jim.Speak();
     Hi, I am Jim
     root [3] MyClass* fred = new MyClass;
     root [4] fred->Speak();
     Hi, I am Anonymous
     root [5] fred->SetName("Fred");
     root [6] fred->Speak();
     Hi, I am Fred
    
    Finally use the ROOT .class command to see what ROOT knows about your class:-
     root [7] .class MyClass
     ===========================================================================
     class MyClass //Example class
      size=0x10
     ...
     compiled)        0:0    0 public: MyClass MyClass(MyClass&);
     (compiled)        0:0    0 public: void ~MyClass(void);
     root [8] .q
    

  7. Now, in the mypackage subdirectory create a ROOT macro MakeTree.c containing:-
    {
       TFile myFile("mypackage.root","RECREATE");
    
    // Create a ROOT Tree
    
       TTree *tree = new TTree("myTree","A tree containing a MyClass object");
    
       MyClass  *myObject = 0;
    
    // Create one branch. 
    
       tree->Branch("myclass", "MyClass", &myObject);
    
    // Fill the tree a few times.
    
       myObject =  new MyClass("Joe");
       tree->Fill();
    
       myObject.SetName("Bill"); 
       tree->Fill();
    
       tree.Write();
       myFile.Close();
    }
    
    and a second ROOT macro ReadTree.c containing:-
    {
       MyClass *myObject = new MyClass();   //object must be created before 
                                            // setting the branch address
       TFile myFile("mypackage.root");
       TTree* T = (TTree*) myFile.Get("myTree");
    
       if ( ! T ) {
         cout << "Cannot find tree !! " << endl;
       }
       else {
    
         T.SetBranchAddress("myclass",&myObject);
         Int_t nevent = T.GetEntries();
    
         for (Int_t i=0;  i<nevent;  i++) {
           cout << "Event " << i << endl;
            T->GetEvent(i);
    	myObject.Speak();
         }
       }
    }
    
    If the use of TTrees is new to you take a look the Companion's TTree crib

  8. Finally run ROOT again and run both macros to write and then read back your objects:-
    root [0] gSystem.Load("libmypackage.so");
    root [1] .x mypackage/MakeTree.C
    TFile**         mypackage.root
     TFile*         mypackage.root
      OBJ: TTree    myTree  A tree containing a MyClass object : 0
      KEY: TTree    myTree;1        A tree containing a MyClass object
    root [2] .x mypackage/ReadTree.C
    Event 0
    Hi, I am Joe
    Event 1
    Hi, I am Bill
    root [3]
    






Last Modified: $Date: 2005/09/06 17:00:40 $
Contact: lartey@fnal.gov
Page viewed from http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/soft_use_test.html
Fermilab
Security, Privacy, Legal Fermi National Accelerator Laboratory