! ========================================================================== ! Running makent ! ========================================================================== ! This manual shows how to create a rather complicated ntuple from a Monte ! Carlo DST file. Our ntuple will be at the TRACK-LEVEL -- one record per ! track -- and will only contain tracks that were successfully reconstructed ! and came from the target cell. ! To use makent, you must create an ntuple description file, called makent.in ! by default. This entire manual is in the form of such a file. ! The description file is provided to the makent script via the '-in' ! command-line argument; if you don't specify this argument, makent will ! look for the default 'makent.in'. ! Running makent is simple once you have the descriptor file. To make the ! ntuple described in this manual from a couple of Monte Carlo DST files, ! you'd do this: ! makent -in makent-manual.txt run1.smdst.gz run2.smdst.gz ! As you can already see, lines starting with ! (or #) in your descriptor ! file are considered comments. Inline comments are also supported: ! all text AFTER a ! or # character is ignored. A small note: unless it is ! at the beginning of a line, your ! or # character must be preceded by one ! or more whitespace characters or it will not be considered a comment ! (reason: the DAD parser uses ! in some of its operators). ! A note about the DAD parser ... The makent script is just a frontend to ! hexe (and hister). The real power resides entirely in the hexe program. ! Your ability to perform CALCULATIONS comes entirely from hexe's support ! for DAD parser expressions, so you should familiarize yourself with them. ! A complete description is provided on this web page: ! http://www-hermes.desy.de/dad/parser.html ! It is just one click from the DAD homepage. ! After you've read through this extended description, you can get a ! quick-reference guide by typing 'makent -example'. ! ------------------------- ! Some command-line options ! ------------------------- ! The makent script supports a variety of command line options. ! Type 'makent -help' to see them all. Just a little note here: ! four of the options deal with run numbers: ! ! -min only process run numbers .ge. minrun ! -max only process run numbers .le. maxrun ! -runs alternate way to specify run range ! -addrun add run number from input FILENAME to ntuple ! ! The run number consulted by these options comes from your input FILENAME, ! not the file contents. This is particularly useful for Monte Carlo ! files, which often do not have a proper run number in the ADAMO tables. ! It also means that you can process a range of runs quite easily ! using UNIX wild cards. Here's an example of how to process runs ! 310 through 346 from the 02a main production: ! ! makent /production/hrc/02a/root/run003[1-4]?/hrc?????.devents.gz -max 346 ! ! Also note the -ievgen option. When working with Monte Carlo files, the ! total number of generated events is a crucial parameter for generating ! absolutely-normalized histograms. The -ievgen option allows you to ! supply this number to your output ntuple(s) as entry 'ievgen', with ! constant value . If you specify -ievgen 0, -ievgen , ! or -ievgen auto, the number of generated events will be calculated ! automatically (very convenient)! This works fine as long as your ! event files are NOT FILTERED. If you *have* filtered your Monte Carlo ! event files, events will be missing and so you must provide the ievgen ! number on the command line from your GMC NORM files. ! ========================================================================== ! The Main Table ! ========================================================================== ! First specify the MAIN ADAMO table from which your ntuple will draw ! its data. Your ntuple will contain one record for each ROW of this table. ! Also, you will only be able to store data from this table and from tables ! that are connected to it by a link (in either direction). ! In this example, we are only interested in tracks that were reconstructed, ! so we will cycle through g1Track (rather than g1MTrack). MAINTABLE: g1Track ! ========================================================================== ! Row Condition on Main Table (optional) ! ========================================================================== ! If you like, you can specify a CONDITION: only rows of the main table which ! pass this condition will be considered. The condition can be any dad parser ! expression involving entries from the main table. For example, let's ! impose a condition to cut out tracks that came from outside the target cell: CONDITION: (abs(rVertZ)<18)and(abs(rVertD)<0.75) ! That's not the whole story, however: you *CAN* include variables ! from other tables in your condition! (e.g. you could impose a Q2 cut ! on your tracks, even though the Q2 variable comes from the non-main ! table g1MEvent). We'll come back to that at the very end of this file. ! ========================================================================== ! Data from the Main Table ! ========================================================================== ! Next we specify the entries in your ntuple. First we will shuffle data from ! the main ADAMO table to the ntuple. The format for these lines is: ! [ ] ! where ! = name of variable to create in ntuple ! = ADAMO variable from main table ! = optional format specifier for hister: ! R (real) is the default, otherwise I (integer), ! or C (e.g. C4, C16) for a string of length ievent iEvent I ! event number the rTheta R ! track polar angle phi rPhi ! track azimuthal angle ! I'll take this opportunity to point out something important: ADAMO *is* ! case sensitive. You must pay attention to this when specifying any ! ADAMO variable or table name. To find out what's correct, consult the ! appropriate DDL file(s): g1.ddl and/or g1_MC.ddl for DST files, ! MCARLO.ddl for GMC or HMC files, HRC.ddl for HRC files, etc... ! Your specifiers go straight to hexe, so they can also ! be DAD parser expressions! You can thus load your ntuple with ! CALCULATIONS based on the input data: p abs(rEnergy) ! track momentum imethod iMethod&255 I ! tracking method in first 8 bits ! (0,1,2 = STD,NOVC,FITVC) zvx rVertZ ! z position of track origin tvx rVertD ! transv sep betw track and beam thx atan2(sin(rTheta)*cos(rPhi),cos(rTheta)) ! angle projection onto xz plane ! You can also write your calculations in a different format: thy atan2(sin($1)*sin($2),cos($1)) rTheta rPhi R ! I guess this second syntax is clear. You can use the meta-variables $1 ! through $9 in your DAD parser expression, then specify the corresponding ! replacement variables in additional fields. The (optional) format ! specifier goes at the end, as before. NOTE: It is best that you get ! into the habit of using this $n syntax all the time ... as you'll see ! later it's the *only* syntax that works with data from NON-main tables, ! so you might as well use it all the time. ! If you only want to pull data from a SINGLE table you're done, ! there is no need to read further. :-) ! ========================================================================== ! Data from Secondary Tables ! ========================================================================== ! Thanks to the power of hexe you can also access data from other ADAMO tables. ! There are three types of secondary tables that you can pull in: ! (1) Tables which are connected to the main table via some ADAMO relation. ! (makent accesses these via the dad parser commands NATREL and NAFREL.) ! (2) Tables where you know exactly which row you want (e.g. 1-row tables) ! (makent accesses these via the dad parser command GETROW.) ! (3) Tables where you only want a count of the number of rows ! (makent gets this info via the dad parser commands COUNTTABLE.) ! Please note: only versions of dad after 1.5 support NAFREL or GETROW. ! You must therefore be using release r20 or later of the HERMES software. ! --------------------------- ! Secondary tables via NATREL ! --------------------------- ! First let's add some basic information to our ntuple from the g1MTrack ! table. Each row of g1Track is linked to some row from g1MTrack ! containing the *generated* Monte Carlo information for the particle. ! We introduce this new table with the TABLE specifier: TABLE: g1MTrack g1Track_g1MTrack ! The important second field informs makent of the DIRECTION of the link ! between this table and the main table. In this example we are invoking ! the following link from g1_MC.ddl: ! ( g1Track [0,1] -> g1MTrack [0,*] ) ! You must use the Fortran-style format 'g1Track_g1MTrack' to specify these ! links (the C-style format 'g1Track.g1MTrack' will not work). ! If your new table is linked to the main one by a generalized (i.e. 'named') ! relationship, you must supply the name you want in the second field. ! For example, if you wanted to pull in RICH PID calculations based on the ! IRT method, you would use this line: ! TABLE: smRICH g1Track_IRT ! Now that we've introduced the new table g1MTrack, we are free to shuffle ! variables from it to the ntuple as before: genthe rTheta genphi rPhi ! -------------------- ! The -keepnull option ! -------------------- ! Now is the time to mention the '-keepnull' command-line option ! to makent. It could happen that some row of the g1Track main table has *NO* ! corresponding Monte Carlo track. Then all fields in your secondary ! table g1MTrack will be NULL (i.e. a really big magic number). You can deal ! with this in two ways: either keep the ntuple record with NULL's in ! the Monte Carlo fields, or else toss the track entirely. The latter is ! hexe's default behaviour: it suppresses all print lines with NULL links. ! If you want to keep the records with NULL's, run makent with the ! '-keepnull' option (which turns on hexe's --pnull option). ! --------------------------- ! Secondary tables via NAFREL ! --------------------------- ! The example above was of a simple NATREL link from the main table ! to the secondary one. We can also pull in tables via 'backwards' ! NAFREL links which point from the secondary table to the main table. ! As an example, we'll grab some PID values from the smTrack table: TABLE: smTrack smTrack_g1Track pulscer rCer ecalo rECalo ! This example will work just fine, since g1Track_smTrack is a 1-to-1 link. ! Most of the important links in the HERMES data files are of this type. ! However, some links are many-to-one, and then this NAFREL association ! is ambiguous. Here is an illustration. Suppose your MAINTABLE was ! the Monte Carlo table g1MTrack, and you wanted to pull in reconstructed ! information from g1Track. You'd introduce your secondary table like this: ! TABLE: g1Track g1Track_g1MTrack ! Trouble is, a row of g1MTrack may be associated with *more than one* ! reconstructed track. Which one should hexe pick? Hexe just picks the ! *first match*, and informs you that it did so. You need to be aware ! of this behaviour. ! ------------------------------------------------------- ! Accessing one-row tables or specific rows with TABLEROW ! ------------------------------------------------------- ! Our example ntuple is at the track level, but may well want to include ! some information from the event-level tables. A good example is the ! Monte Carlo event weight, stored in g1MEvent_Weight. Unfortunately, ! we'd have to navigate TWO ADAMO relations to get there from the ! g1Track maintable. But no problem, hexe's new GETROW command allows ! you to access a disconnected table as long as you know what row you want ! ... and most of the event-level tables at HERMES have only one row. ! The TABLEROW specifier allows you to access a specific row of a table: TABLEROW: g1MEvent 1 weight Weight ! The '1' tells makent to access the first row. Since this is the default ! row number, you can omit the '1'. For users examining GMC output files, ! TABLEROW is very useful for retrieving the generator-specific information ! in the mcUser table. ! -------------------------------------------------- ! Counting the number of rows in a table with COUTAB ! -------------------------------------------------- Occasionally, you might simply want to get a count of the number of rows in a table. In this case, you do not need to specify ANY link to the maintable --> the table you're counting can be completely disconnected. The syntax is simple: COUTAB: g1MVert nvert The order of arguments is a bit unusual for makent: the first one (g1MVert) is the table, the second one (nvert) is the ntuple variable name. Naturally, all such counter variables are given Integer type. ! ---------------------------------- ! Calculations with Secondary Tables ! ---------------------------------- ! Let's return to the g1MTrack table and grab some more information: TABLE: g1MTrack g1Track_g1MTrack genp abs($1) rP genthx atan2(sin($1)*cos($2),cos($1)) rTheta rPhi genthy atan2(sin($1)*sin($2),cos($1)) rTheta rPhi iltype iLType I ictype icType I ! As you can see from the above, CALCULATIONS with dad parser expressions ! are supported in secondary tables ... but *ONLY* the meta-variable $n syntax ! can be used. This is important: you MUST use the $1 through $9 ! meta-variables in all functions involving secondary tables. Otherwise, ! makent cannot know that your second field is a function at all, and will ! not know how to parse it. (Functions involving only maintable variables ! are different because they require no parsing at all.) ! ================================================================= ! Calculations involving Multiple Tables or Predefined NT Variables ! ================================================================= ! But the fun continues! You can MIX variables from different tables in ! your functions. Here we calculate the difference between generated ! and reconstructed momentum: pdiff abs($1-$2) rP g1Track_rEnergy ! Since the first argument 'rP' has no table specification, it is taken from ! the current table, g1MTrack. (The 'current table' is just the one that ! appeared most recently in a MAINTABLE, TABLE, or TABLEROW specifier.) ! You can mix in variables from any table that is specified with a ! MAINTABLE, TABLE, or TABLEROW line somewhere in your file. The placement ! of the specifier is irrelevant: makent makes a first pass through ! your input file to figure out all the table links. ! Finally, you can also use previously defind NTUPLE VARIABLES in ! your calculations. You invoke these as if they came from a mythical ! table called 'NT': pdiff2 abs($1-$2) NT_genp NT_p ! Here order is important: since variable parsing is done on makent's ! second pass, the ntuple variables 'genp' and 'p' must be defined ! EARLIER in your file than where you use them. Note that genp and p ! are themselves functions ... this is not a problem. :-) To be safe, ! the script adds parentheses around your functions-imbedded-within-functions ! --> you can thus treat each NT_* object as an atom, the operator-precedence ! you expect will be obeyed. ! Finally, let's come back to the CONDITION statement introduced much earlier. ! Recall that a CONDITION allows you to place cuts on each row of the ! main table: only those rows which pass your condition will be processed. ! When we introduced CONDITIONs earlier, we only used variables from the ! main table. But your conditions can also include predefined ntuple variables, ! possibly involving data from secondary tables. The only requirement is ! that the ntuple variables are defined *earlier* in the makent.in file ! that the CONDITION statement. That's not a problem since the CONDITION ! can appear anywhere in the file, even at the end. ! Here's a classic example ... ! GNOME xxx: whoo boy, $table name for GETROW ! connections is mcEvent1, not mcEvent ... and $table = Parent concept, ! how to explain simply? ! COUTAB: mcTrack --> mcTrack0 ! TABLEROW: mcTrack 5 --> mcTrack5 ! TABLE: xxx mcTrack_endtable --> xxx