BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//
//-------------------------------------------------------------------//
//                                                                   //
//    BrChkvParameters  	                	             //
//                                                                   //
//    Parameters describing the physical properties of the C1 tubes. //
//    Some of these are presently simulation parameters others are   //
//    relevant to both simulations and reconstruction.               //
//                                                                   //
//-------------------------------------------------------------------//

//
// $Id: BrChkvParameters.cxx,v 1.5 2001/09/24 07:10:50 ekman Exp $
// $Author: ekman $
// $Date: 2001/09/24 07:10:50 $
//
//--------------------------------------------------------------------//
//

#ifndef WIN32
#include <iostream>
#include <iomanip>
#else
#include <iostream.h>
#include <iomanip.h>
#endif

#ifndef BRAT_BrChkvParameters
#include "BrChkvParameters.h"
#endif
#ifndef BRAT_BrUnits
#include "BrUnits.h"
#endif

//__________________________________________________________________
ClassImp(BrChkvParameters);

//__________________________________________________________________
 BrChkvParameters::BrChkvParameters()
{
  // Constructor: DO NOT USE
  // Use BrDetectorParams(Char_t, Char_t ) instead
  fXArrayNumber = 0;
  fYArrayNumber = 0;
  fXYTube = 0;
  //fXArrayXPos = 0;
  //fYArrayYPos = 0;
}


//__________________________________________________________________
 BrChkvParameters::BrChkvParameters(Char_t *name, Char_t *title)
  : BrDetectorParamsBase(name, title)
{
  // Standard constructor. 
  // the name should be that of the associated detector 
  // e.g. "C1" or "RICH"

  fXArrayNumber = 0;
  fYArrayNumber = 0;
  fXYTube = 0;
  //  fXArrayXPos = 0;
  // fYArrayYPos = 0;

  SetDefaultParameters();


}

//__________________________________________________________________
 BrChkvParameters::BrChkvParameters(Char_t *name, 
				   Char_t *title, 
				   Char_t *filename)
  : BrDetectorParamsBase(name, title, filename)
{
  // Constructor which also reads parameters in from a configuration file
  // the name should be that of the associated detector
  // e.g. "C1" or "RICH"

  fXArrayNumber = 0;
  fYArrayNumber = 0;
  fXYTube = 0;
  //fXArrayXPos = 0;
  //fYArrayYPos = 0;

  SetDefaultParameters();

  ReadASCIIFile(filename);

}

//__________________________________________________________________
 BrChkvParameters::~BrChkvParameters()
{
  // Default destructor
  delete [] fXArrayNumber;
  delete [] fYArrayNumber;
  delete [] fXArrayXPos;
  delete [] fYArrayYPos;

  for(Int_t i = 0; i < fNoTubesX; i++)
    delete [] fXYTube[i];

  delete [] fXYTube;
}

//__________________________________________________________________
 void BrChkvParameters::SetDefaultParameters()
{
  // Set a set of reasonable default parameters.
  // This is mainly to ensure that the private members are
  // initialized with values that do not give rise to any
  // problems in the methods which uses these parameters;
  //

  // c1 parameters
  TString name(GetName());
  name.ToUpper(); 

  if (name == "C1") { 
    fNoTubes   = 32; // Number of tubes for C1
    fNoTubesX  = 8; // Number of tubes for C1
    fNoTubesY  = 4; // Number of tubes for C1
    fTubeSize = 2.5*BrUnits::inch; // 6.35 cm
    fXOffset  = 0.0;
    fYOffset  = 0.0;
    MakeC1Map();
  } 

  // RICH parameters
  else if (name == "RICH") { 
    fNoTubes   = 320; // Number of tubes for RICH
    fNoTubesX  = 20; // Number of tubes for RICH
    fNoTubesY  = 16; // Number of tubes for RICH
    fTubeSize = 1.35; // DO: I hope in cm...
    fXOffset = 0.0;
    fYOffset = 0.0;
    MakeRICHMap();
  } 
  else {
    Fatal("SetDefaultParameters", 
	  "Invalid detector name. Only "C1" or "RICH" is valid");
    return;
  }
  
}

//__________________________________________________________________
 void BrChkvParameters::SetASCIIParameters(Char_t *line) 
{
  // Interpret a line for DC params.  Form is ParamName:value.  Eg 
  // Eg fTwopar:.20 or fEff:  0.95
  Char_t ParamName[80];

  // Find first non-blank character in the line 
  // (in case user didn't start in column 1
  Int_t i;
  for(i = 0; i < (Int_t)strlen(line);i++)
    if (strncmp(&line[i]," ",1)) 
      break;

  //Copy that to ParamName
  strcpy(ParamName,&line[i]);
  
  Char_t *iloc = strchr(ParamName,':');
  Char_t *value_loc = iloc+1;
  if (iloc) {
    iloc[0] = 0;    //blank out the semicolon
    if (!strcasecmp(ParamName,"fNoTubes"))
      sscanf(value_loc, "%d", &fNoTubes);
    
    else if (!strcasecmp(ParamName,"fNoTubesX"))
      sscanf(value_loc, "%d", &fNoTubesX);
    
    else if (!strcasecmp(ParamName,"fNoTubesY"))
      sscanf(value_loc, "%d", &fNoTubesY);
    
    else if (!strcasecmp(ParamName,"fTubeSize"))
      sscanf(value_loc, "%lf", &fTubeSize);
    
    else if (!strcasecmp(ParamName,"fXOffset"))
      sscanf(value_loc, "%lf", &fXOffset);
    
    else if (!strcasecmp(ParamName,"fYOffset"))
      sscanf(value_loc, "%lf", &fYOffset);
    
    else {
      Warning("ReadASCIIParameters", "%s is not "
	      "one of the parameters ", ParamName);
      return;
    }
    return; //this is a normal return
  }

  else {
    cout << "Error, : missing to delineate name from value" << endl;
    cout << "The string is "  << line << endl;
    cout << "No value set!!!" << endl;
    return;
  }
}
  
//____________________________________________________________________
 void BrChkvParameters::MakeC1Map()
{
  // C1 mapping
  //
  // There are 32 (8 (x) * 4 (y))
  // 
  // The mapping is as follows :
  //
  //   Internal tube numbering and position
  //   y/x   0   1   2   3   4   5   6   7
  //     3   8   9  10  11  12  13  14  15
  //     2   0   1   2   3   4   5   6   7
  //     1  16  17  18  19  20  21  22  23
  //     0  24  25  26  27  28  29  30  31
  //
  //  NB!!!!
  //  When you give tubenumbers to the other methods they
  //  should be from 1-32.
  //
  // Each readout section is 2.5 inch * 2.5 inch
  
  if (fXArrayNumber != 0 || fYArrayNumber != 0 || fXYTube != 0) {
    Warning("MakeC1Map", "C1 Map was already made");
    return;
  }  
  
  fXArrayNumber = new Int_t[fNoTubes];
  fYArrayNumber = new Int_t[fNoTubes];
  fXYTube       = new Int_t*[fNoTubesX];

  for(Int_t i = 0; i < fNoTubesX; i++) {
    fXYTube[i] = new Int_t[fNoTubesY];
    for(Int_t j = 0; j < fNoTubesY; j++)
      fXYTube[i][j] = -1;
  }
  
  for(Int_t i = 0; i < fNoTubes; i++) {
    Int_t column = i%fNoTubesX;
    Int_t xCoord = column;
    
    Int_t y = i/fNoTubesX;
    Int_t yCoord = 0;
    if (y < 2)
      yCoord = 2 + y;
    else 
      yCoord = 3 - y;
    
    if (!TestRange(xCoord, yCoord)) {
      Fatal("MakeC1Map", "xCoord(%d) or yCoord(%d) "
	    "out of range", xCoord, yCoord);
      return;
    }

    if (fXYTube[xCoord][yCoord] != -1) {
      Fatal("MakeC1Map", "Tube %d trying to go (%d, %d) "
	    "where tube %d is already", i+1, xCoord, yCoord, 
	    fXYTube[xCoord][yCoord] + 1);
      return;
    }
    
    fXArrayNumber[i] = xCoord;
    fYArrayNumber[i] = yCoord;
    fXYTube[xCoord][yCoord] = i;
    
  }
}

//____________________________________________________________________
 void BrChkvParameters::MakeRICHMap()
{
  // RICH mapping
  //
  // There are 320 (20 (x) * 16 (y))
  // 
  // The mapping is as follows seen from the particle going from the
  // mirror towards the detector :
  //
  // They are grouped in groups of 4 as this
  //  
  //               ....  09-12  
  //   ..... 69-72 37-40 05-08   
  //   ..... 65-68 33-36 01-04   
  //
  // Note that 01-04 and 289-292 (lower corners) are not instrumented
  // 
  // Additional notes :
  // The mirror is spherical
  //          -------  
  //                 <- focal length = 150 cm  
  // ______________   (center mirror to center readout plane)
  //                   (the angle is 2*9 degrees) 
  // (mirror and perpendicalr is 9 degrees)
  //
  // Each pixel is 1.2 cm * 1.2 cm
  
  if (fXArrayNumber != 0 || fYArrayNumber != 0 || fXYTube != 0) {
    Warning("MakeRICHMap", "RICH Map was already made");
    return;
  }  
  
  fXArrayNumber = new Int_t  [fNoTubes];
  fYArrayNumber = new Int_t  [fNoTubes];
  fXYTube       = new Int_t* [fNoTubesX];

  for(Int_t i = 0; i < fNoTubesX; i++)
    fXYTube[i] = new Int_t[fNoTubesY];
  
  // Initialize fXYTube to -1
  for(Int_t i = 0; i < fNoTubesX; i++)
    for(Int_t j = 0; j < fNoTubesY; j++)
      fXYTube[i][j] = -1;
  
  for(Int_t i = 0; i < fNoTubes; i++) {
    
    Int_t xCoord = i/(fNoTubesY*2);
    
    Int_t yCoord = (i - xCoord*fNoTubesY*2)/4;

    xCoord = fNoTubesX-2 - 2*xCoord;
    yCoord *= 2;

    // Now the coordinates for x and y should be
    // x (0, 2, 4, 6, 8, 10, 12, 14, 16, 18)
    // y (0, 2, 4, 6, 8, 10, 12, 14)
    
    const Int_t offsetY = i%4;
    Int_t effectiveOffsetY = offsetY;
    
    if (2*xCoord < fNoTubesX  || 2*yCoord < fNoTubesY) {
      
      // Most of the pixels (3/4) are split this way 
      // ///|
      // ///|
      // ---*---
      // ///|///
      // ///|///
      // (where the number is the offset)
      // 1|2
      // -*-
      // 0|3   (clockwise)   
      // The position calculated so far is that for offset == 0
      
    }
 
    else {
      
      // 1/4 of the pixels are split in a different way 
      //    |///
      //    |///
      // ---*---
      //    |
      //    |
      // 1|3
      // -*-
      // 0|2   
      // To correct for this I switch 2 <-> 3
      if (offsetY == 2) 
	effectiveOffsetY = 3;
      
      else if (offsetY == 3) 
	effectiveOffsetY = 2;
      
    }
    
    if (effectiveOffsetY == 0) {
      // do nothing
    } 
    else if (effectiveOffsetY == 1)
      yCoord += 1;
    else if (effectiveOffsetY == 2) {
      xCoord += 1;
      yCoord += 1;
    } 
    else if (effectiveOffsetY == 3)
      xCoord += 1;
    else {
      Warning("MakeRICHMap", "Something is wrong with the algorithm!!!!");
      return;
    }
    
    if (!TestRange(xCoord, yCoord)) {
      Fatal("MakeRICHMap", "xCoord(%d) or yCoord(%d) "
	    "out of range", xCoord, yCoord);
    }

    if (fXYTube[xCoord][yCoord] != -1) {
      Fatal("MakeRICHMap", "Tube %d trying to go (%d, %d) "
	    "where tube %d is already", i+1, xCoord, yCoord, 
	    fXYTube[xCoord][yCoord] + 1);
    }
    
    fXArrayNumber[i] = xCoord;
    fYArrayNumber[i] = yCoord;
    fXYTube[xCoord][yCoord] = i;
  }

  // (x,y) coordinates does not scale with XY tube (small offsets
  // between 2x2 tube cells
  // definition of x and y position of x and y arrays

  Float_t xpos[] = {-5.795, -4.685, -3.175, -2.065, -0.555, 
		    0.555,    2.065,  3.175,  4.685, 5.795,
		    -5.795, -4.685, -3.175, -2.065, -0.555, 
		    0.555,    2.065,  3.175,  4.685, 5.795};
  
  for (Int_t i=0; i<20; i++) {
    if (i<10)
      fXArrayXPos[i] = xpos[i] - 6.525 - 0.1;
    if (i>=10)
      fXArrayXPos[i] = xpos[i] + 6.525 + 0.1;
  }

  Float_t ypos[] =  {-4.485, -3.375, -1.865, -0.755,
		     0.755,  1.865, 3.375, 4.485,
		     -4.485, -3.375, -1.865, -0.755,
		     0.755,  1.865, 3.375, 4.485};
  
  for (Int_t i=0; i<16; i++) {
    if (i<8)
      fYArrayYPos[i] = ypos[i] - 5.215 - 0.1;
    if (i>=8)
      fYArrayYPos[i] = ypos[i] + 5.215 + 0.1;
  }
}

//____________________________________________________________________
 BrVector3D BrChkvParameters::GetTubePosition(Int_t tubeNo) const
{
  // Returns the xy position of the tube with respect to 
  // C1 - the backplane
  // RICH - the pixeldetector plane

  const Int_t xCoord = fXArrayNumber[tubeNo-1];
  const Int_t yCoord = fYArrayNumber[tubeNo-1];

  TString name(GetName());
  name.ToUpper(); 

  if (name == "C1") {
    Double_t x = Double_t(xCoord) - Double_t(fNoTubesX)/2 + 0.5;
    Double_t y = Double_t(yCoord) - Double_t(fNoTubesY)/2 + 0.5;
    
    // scale with the tubesize
    x *= fTubeSize;
    y *= fTubeSize;
    
    // add the offsets
    x += fXOffset;
    y += fYOffset;
    
    BrVector3D pos(x, y, 0);
    return pos;
  }
  
  if (name == "RICH") {
    BrVector3D pos(fXArrayXPos[xCoord], fYArrayYPos[yCoord], 0);
    return pos;
  }  
}

//____________________________________________________________________
 Int_t BrChkvParameters::GetClosestTube(Double_t x, Double_t y) const
{
  // NB: only valid for C1 !!!!!!!!!!!!!
  // Return the tube number of the tube closest to the point
  // (x, y) on 
  // C1 - the backplane
  // RICH - the pixeldetector plane

  TString name(GetName());
  name.ToUpper();
  if (name == "C1") {
    // Subtract the offsets
    x -= fXOffset;
    y -= fYOffset;
    
    // downscale with the tubesize
    x /= fTubeSize;
    y /= fTubeSize;
    
    // Add "half the length" 
    // add the offsets
    x += fNoTubesX/2;
    y += fNoTubesY/2;
    
    // Convert to integer array position
    Int_t xCoord = Int_t(x); // DO: Int or Nint ??
    Int_t yCoord = Int_t(y);
    
    // return tubeNo if valid
    if (!TestRange(xCoord, yCoord)) {
      if (fVerbose>11) {
	Warning("GetClosestTube", "xCoord(%d) or yCoord(%d) "
	      "out of range", xCoord, yCoord);
      }
      return 0;
    }
    
    const Int_t tube = fXYTube[xCoord][yCoord];
    return tube+1;  
  }
  if (name == "C1") {
    return 0;
  }
}

//____________________________________________________________________
 Int_t BrChkvParameters::GetTubeWithDirection(Int_t tubeNo, 
					     Int_t x, Int_t y) const
{
  // Returns the tube no which are sitting in the direction 
  // x, y from tubeNo
  // For C1 we have the map (Do Print("m") to get a pic)
  //   y/x   0   1   2   3   4   5   6   7
  //     3   9  10  11  12  13  14  15  16
  //     2   1   2   3   4   5   6   7   8
  //     1  17  18  19  20  21  22  23  24
  //     0  25  26  27  28  29  30  31  32
  //
  //   ******************************************************
  //   Watch it!!!! The internal fXArray, fYArray and fXYTube
  //   numbering is different!:
  //   ******************************************************
  //
  //   Internal tube numbering and position
  //   y/x   0   1   2   3   4   5   6   7
  //     3   8   9  10  11  12  13  14  15
  //     2   0   1   2   3   4   5   6   7
  //     1  16  17  18  19  20  21  22  23
  //     0  24  25  26  27  28  29  30  31

  // GetTubeWithDirection(2, 1, 0) would return 3
  // GetTubeWithDirection(2, 2, -1) would return 20
  // and if no tube is found then -1 is returned
  // GetTubeWithDirection(2, 2, 2) would return -1

  const Int_t xCoord = fXArrayNumber[tubeNo-1] + x;
  const Int_t yCoord = fYArrayNumber[tubeNo-1] + y;
  
  if (!TestRange(xCoord, yCoord))
    return -1;

  return fXYTube[xCoord][yCoord]+1;  
} 

//____________________________________________________________________
 Bool_t BrChkvParameters::TestRange(Int_t x, Int_t y) const
{
  // Test if the index in the xy array is out of range
  // If out of range return kFALSE else return kTRUE

  if (x < 0 || x >= fNoTubesX || y < 0 || y >= fNoTubesY) {
    if(fVerbose>15)
      Warning("TestRange",Form("Tube at (%d,%d) out of range.",x,y)); 
    return kFALSE;
  }
  
  return kTRUE;
}

//____________________________________________________________________
 void BrChkvParameters::Print(Option_t *option="") const
{
  // The print method
  // options :
  // m - also print tube mapping
  // d - print author/date/lastmodified etc.  
  
  TObject::Print(option); 
  
  cout << " Number of tubes = " << setw(8) << fNoTubes << endl
       << "     x (columns) = " << setw(8) << fNoTubesX << endl
       << "     y (rows)    = " << setw(8) << fNoTubesY << endl
       << " Tube size       = " << setw(8) << fTubeSize << endl
       << " X offset        = " << setw(8) << fXOffset << endl
       << " Y offset        = " << setw(8) << fYOffset << endl;
  
  TString opt(option);
  opt.ToLower(); 
  
  if (opt.Contains("m")) {
    cout << endl << "Tube mapping : " << endl;
    cout << setw(4) << "y/x" << setw(4) << "|";

    for(Int_t j = 0; j < fNoTubesX; j++)
      cout << setw(4) << j;
    cout << endl;

    for(Int_t j = 0; j < fNoTubesX + 2; j++)
      cout << setw(4) << "----";
    cout << endl;

    for(Int_t i = fNoTubesY - 1; i >= 0; i--) {
      for(Int_t j = -1; j < fNoTubesX; j++)
	if (j == -1)
	  cout << setw(4) << i << setw(4) << "|";
	else
	  cout << setw(4) << fXYTube[j][i]+1;
      cout << endl;
    }
    cout << endl;
  } // end option m
  
  if (opt.Contains("d")) 
    cout << endl 
         << "  Original authors: D. Ouerdane/ P.Christiansen" << endl
         << "  Last Modifications: " << endl 
         << "    $Author: ekman $" << endl  
         << "    $Date: 2001/09/24 07:10:50 $"   << endl 
         << "    $Revision: 1.5 $ " << endl  
         << endl 
         << "-------------------------------------------------" << endl;
}

//__________________________________________________________________
//
// $Log: BrChkvParameters.cxx,v $
// Revision 1.5  2001/09/24 07:10:50  ekman
// Added arrays to give exact tube position on RICH image plane - changed
// methods to get tube position and nearest tube.
//
// Revision 1.4  2001/08/21 10:02:02  ekman
// Changed verbose level in TestRange method.
//
// Revision 1.3  2001/08/21 09:59:19  ekman
// Fixed bug in GetTubeWithDirection() method.
//
// Revision 1.2  2001/07/31 09:30:59  ouerdane
// Merged version of BrDetectorParamsChk and BrChkvParameters
// The first one is obsolete.
// The last one has class version number 2
//
// Revision 1.1  2001/07/20 16:01:50  ouerdane
// Added new clas for cherenkov detector parameters: BrChkvParameters
// works like the other classes (eg. BrDetectorParamsTof) and
// reads the number of tubes of C1 or RICH in DetectorParameters.txt
//
//

This page automatically generated by script docBrat by Christian Holm

Copyright ; 2002 BRAHMS Collaboration <brahmlib@rcf.rhic.bnl.gov>
Last Update on by

Validate HTML
Validate CSS