Print

Print


Hey Jeremy,

Back when we wrote the ECal geometry code, we certainly didn’t provide any general facilities we didn’t need for what we were doing (reproducing Maurik’s clustering algorithm - AKA trigger clustering.)  I really think it would make sense to add a public method the HPSEcal3 that hands you crystal (center) position if given the (ix,iy) indexes.  Better yet, I don’t see any reason why Nathan, Kyle, Holly... shouldn’t add whatever utility methods to the class that they want, since there may be other things (e.g. position of the crystal center in x,y at some specified depth in z.)  It’s even easy with the utilities in Geom3d to do more subtle things, like ask whether a specific x,y,z is inside a crystal, which crystal it is inside, etc. etc. etc.  I can well imagine that for more subtle analysis, one may want a way of doing these things.

Tim

On Feb 6, 2015, at 10:27 PM, McCormick, Jeremy I. <[log in to unmask]> wrote:

Hi, Nathan.

This exists already, though it isn’t a one-liner.  

A complete example including all necessary Driver setup would be something like…

public class FindChannelExample extends Driver {
    
    EcalChannelCollection channels;
    IIdentifierHelper helper;
    int sys;

    public void detectorChanged(Detector detector) {
        helper = detector.getSubdetector("Ecal").getDetectorElement().getIdentifierHelper();
        channels = DatabaseConditionsManager.getInstance().getCollection(EcalChannelCollection.class);                
        sys = detector.getSubdetector("Ecal").getSystemID();
    }
    
    public void process(EventHeader event) {
        List<CalorimeterHit> hits = event.get(CalorimeterHit.class, "EcalCalHits");
        for (CalorimeterHit hit : hits) {
            // Get ID from the hit.
            IIdentifier hitId = hit.getIdentifier();
            int ix = helper.getValue(hitId, "ix");
            int iy = helper.getValue(hitId, "iy");
            
            // Find channel from X and Y values.
            GeometryId geomId = new GeometryId(helper, new int[] {sys, ix, iy});
            EcalChannel channelFromGeomId = channels.findChannel(geomId);
            
            // Better way is finding by cell ID from hit directly.
            EcalChannel channelFromCellId = channels.findGeometric(hit.getCellID());
        }               
    }
}

If you have a cellID from a RawCalorimeterHit or CalorimeterHit, then you can just use that directly to lookup the corresponding channel.  (as shown)

Potentially some of this complexity could be hidden with a simpler API, but I don’t this is all that complicated.

—Jeremy

On Feb 6, 2015, at 6:18 PM, Nathan Baltzell <[log in to unmask]> wrote:

Hi Jeremy,

So, basically we lack an easy way to retrieve the EcalChannel given its (x,y) position.
To what class should that functionality be added?  EcalChannel?

Regards,
Nathan



On Feb 6, 2015, at 3:58 PM, "McCormick, Jeremy I." <[log in to unmask]> wrote:

Apologies, my last reply might have been an incomplete draft.

Here’s an example of creating hits directly from the crystal objects in the geometry...

public class IdExample extends Driver {

   IIdentifierHelper helper;
   Subdetector subdet;
   public void detectorChanged(Detector detector) {
       subdet = detector.getSubdetector("Ecal");
       helper = subdet.getDetectorElement().getIdentifierHelper();
   }

   public void process(EventHeader event) {
       for (EcalCrystal crystal : subdet.getDetectorElement().findDescendants(EcalCrystal.class)) {
           IIdentifier id = crystal.getIdentifier();
           CalorimeterHitUtilities.create(0, 0, id.getValue());
       }
   }

}

You can also do something similar based on the EcalChannel conditions….

public class EcalChannelIdExample extends Driver {

   EcalChannelCollection channels;
   int sys;
   IIdentifierHelper helper;
   public void detectorChanged(Detector detector) {
       channels = DatabaseConditionsManager.getInstance().getCollection(EcalChannelCollection.class);
       helper = detector.getSubdetector("Ecal").getDetectorElement().getIdentifierHelper();
       sys = detector.getSubdetector("Ecal").getSystemID();
   }

   public void process(EventHeader event) {
       for (EcalChannel channel : channels) {
           IExpandedIdentifier id = new ExpandedIdentifier();
           int xIndex = helper.getFieldIndex("ix");
           int yIndex = helper.getFieldIndex("iy");
           int sysIndex = helper.getFieldIndex("system");
           id.setValue(xIndex, channel.getX());
           id.setValue(yIndex, channel.getY());
           id.setValue(sysIndex, sys);
           CalorimeterHitUtilities.create(0, 0, helper.pack(id).getValue());
       }
   }
}

I think probably the second way is better because you can easily lookup whatever EcalChannel you want in the collection.

For instance, you can easily add some if statement to look at the X and Y of the channel as you are looping over them to determine if you want to use it or not for creating a hit.

If you have any questions about these examples let me know.  Should be enough to point you in the right direction...

On Feb 6, 2015, at 9:53 AM, Kyle McCarty <[log in to unmask]> wrote:

Hello Jeremy,

I'm not sure if this email got lost. I am trying to create a class for the SSP clusters that extends BaseCluster. I need to do this because I will need to run them through the trigger logic, and it uses BaseCluster objects as arguments. My plan was to create a fake cluster that contains a seed hit with all of the reported energy at the correct cluster location and then populate the rest of the cluster with fake zero energy hits so that cluster.getCalorimeterHits().size() returns the correct cluster size. To do this, I am trying to create the hits with CalorimeterHitUtilities.create(double, double, long), but I am unsure how to get the long cell ID from the ix/iy crystal indices. The conditions database gives ints for both channel and channel ID. Can you explain how to obtain this value or suggest a better way to accomplish what I am trying to do?

Thanks,

Kyle

On Thu, Feb 5, 2015 at 8:53 AM, Kyle McCarty <[log in to unmask]> wrote:
Hello Jeremy,

Is there a quick way to get the "ID" field that is needed when creating a CalorimeterHit object from the x- and y- indices?

I am trying to create an extension of BaseCluster to represent the clusters reported by the SSP. These will never be persisted since they are generated automatically from the SSP bank data during a run, so there is no concern over whether they are LCIO-compatible.

Thanks,

Kyle



Use REPLY-ALL to reply to list

To unsubscribe from the HPS-SOFTWARE list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=HPS-SOFTWARE&A=1





Use REPLY-ALL to reply to list

To unsubscribe from the HPS-SOFTWARE list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=HPS-SOFTWARE&A=1




Use REPLY-ALL to reply to list

To unsubscribe from the HPS-SOFTWARE list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=HPS-SOFTWARE&A=1