|
// $Id: BrMagnetVolume.cxx,v 1.21 2002/08/30 17:35:06 videbaek Exp $ // $Author: videbaek $ // $Date: 2002/08/30 17:35:06 $ // /////////////////////////////////////////////////////////////////////// // // BrMagnetVolume is a BRAHMS data class providing storage and // access function for magnetic volume and fieldinformation. The // base class deals with an effective edge approximation. The idea is // to have derived classes handle more complicated field. // // // The magnet filed can now be set using the currents, rather than reading // field from file. Example // d5magvol->SetCurrent(350,"B") // // The default polynominal coefficients are sets in the constructor. // The class is derived from BrDetectorVolume which maintains the coordinate system // description, while this derived class contains the specific information about // fields description, and current fiels values. // ////////////////////////////////////////////////////////////////////// #include <cstdio> #include <BrIostream.h> #ifndef ROOT_TString #include "TString.h" #endif // // Brat Classes // #include <BrMagnetVolume.h> #include "BrRotMatrix.h" #include "BrVector3D.h" #include "BrPlane3D.h" #include "BrUnits.h" //Needed for MySQL db access #include "BrRunInfoManager.h" #include "BrGeometriesDb.h" ClassImp(BrMagnetVolume); //___________________________________________________________________________ BrMagnetVolume::BrMagnetVolume() { // Constructor. Set counter and list data members to zero. // Don't use this constructor unless you have to and know // what you are doing // Use BrMagnetVolume(Char_t*, Char_t*); fField = 9999; fCurrentRunNo = 0; fHallProbeList = new TObjArray(); } //___________________________________________________________________________ BrMagnetVolume::BrMagnetVolume(const Char_t *name, const Char_t *title, const Char_t *FileName) : BrDetectorVolume(name, title, FileName) { // named constructor // SetDefaultCurrentParameters(name); fField = 9999; fPolarity = 0; //KH 3-Aug-2001 since parameters not initialized to 0 fCurrentRunNo = 0; fHallProbeList = new TObjArray(); } //__________________________________________________________________________ BrMagnetVolume::BrMagnetVolume(const Char_t *name, const Char_t *title) : BrDetectorVolume(name, title) { // named constructor SetDefaultCurrentParameters(name); fField = 9999; fPolarity = 0; //KH 3-Aug-2001 since parameters not initialized to 0 fCurrentRunNo = 0; fHallProbeList = new TObjArray(); } //__________________________________________________________________________ BrMagnetVolume::BrMagnetVolume(const Char_t *name, TObjArray *asciiVolList) : BrDetectorVolume(name, asciiVolList) { // named constructor called by BrGeometryDbManager in MySQL mode SetDefaultCurrentParameters(name); fField = 9999; fPolarity = 0; //KH 3-Aug-2001 since parameters not initialized to 0 fCurrentRunNo = 0; fHallProbeList = new TObjArray(); } //__________________________________________________________________________ BrMagnetVolume::BrMagnetVolume(const Char_t *name, const Char_t *title, Float_t sizeX, Float_t sizeY, Float_t sizeZ, BrVector3D origin, BrRotMatrix rotMatrix, Float_t frontEdge, Float_t backEdge) : BrDetectorVolume(name,title,sizeX,sizeY,sizeZ,origin,rotMatrix) { // ------------------------------------------------------- // Normal constructor specifying origin and rotation matrix // ------------------------------------------------------- fEdgeFront = frontEdge; fEdgeBack = backEdge; fField = 9999; fPolarity = 0; //KH 3-Aug-2001 since parameters not initialized to 0 fCurrentRunNo = 0; fHallProbeList = new TObjArray(); SetDefaultCurrentParameters(name); } //__________________________________________________________________________ BrMagnetVolume::~BrMagnetVolume() { // DTOR fHallProbeList->SetOwner(kTRUE); delete fHallProbeList; } //__________________________________________________________________________ void BrMagnetVolume::SetDefaultCurrentParameters(const Char_t* name) { // ----------------------------------- // Default current to field values. // RD 12/47/2000 // ----------------------------------- if(!strcasecmp("D5",name)){ fA = 17.25; fB = 6.03; fC = -0.00003; } else if(!strcasecmp("D1",name)){ fA = -54.2; fB = 3.8; fC = -0.00005; } else if(!strcasecmp("D2",name)){ fA = -106.3; fB = 6.389; fC = -0.00024; } else if(!strcasecmp("D3",name)){ fA = -24.96; // Ramiro from 27/03/2002 (PS) fB = 4.251; // Ramiro from 27/03/2002 (PS) fC = -0.00004784; // Ramiro from 27/03/2002 (PS) } else if(!strcasecmp("D4",name)){ fA = 128.5; // Ramiro from 21/03/2002 (PS) fB = 4.399; // Ramiro from 21/03/2002 (PS) fC = 0.00001658; // Ramiro from 21/03/2002 (PS) } else { Error("SetDefaultCurrentParameters","Invalid magnet: %s specified",name); } } //___________________________________________________________________________ void BrMagnetVolume::ListParameters() const { // ---------------------------------------------- // List all parameters, maybe should be changed // to Print(const Option_t*). // 2/22/02 - Slated to become obsolete - use Print() instead // ---------------------------------------------- Warning("ListParameters","Obsolete - Use Print() instead"); Print("d"); } //_____________________________________________________________________________ void BrMagnetVolume::Print(Option_t* option) const { // Options: // B Basic information // D Detector information // TString opt(option); opt.ToLower(); // Basic information if (opt.Contains("b")) cout << "BrMagnetVolume: " << GetName() << " - " << GetTitle() << endl; if (opt.Contains("d")) { const BrRotMatrix* rotm = fSystem.GetRotMatrix(); cout << "Magnet Name is " << GetName() << " Type is : " << fFieldType << endl; cout << " Size" << setw(6) << fSize[0] << setw(6) << fSize[1] << setw(6) << fSize[2] << endl; cout << " Position" << setw(6) << fSystem.GetOrigin() << endl; cout << *rotm << endl; cout << "Effective Edges " << setw(8) << fEdgeFront << setw(8) << fEdgeBack << endl; cout << "Magnetic Field " << setw(8) << fField << endl; cout << " BdL " << setw(8) << GetBdl() << endl; } } //___________________________________________________________________________ Bool_t BrMagnetVolume::ReadASCIIFile(Char_t *FileName, Char_t *DetectorName) { // ------------------------------------------------------------------ // Read Magnet parameters from a field file. Organized in a similar // way as to the geometry, but has additional information on the // field values. Each entry should have the following data. // *** // As of (12/11/98) GBRAHMS+gbr2c.f does not yet generate this. // // // MAGNET= D5 // gap x = 35.000 cm // gap y = 10.000 cm // gap z = 76.200 cm // rotation ang = 34.000 deg. // gap center x = 106.247 cm // gap center y = 0.000 cm // gap center z = 157.517 cm // Type=edge // Field (KG) = -6.00 // z min = -42.000 cm // z max = 42.000 cm // // ------------------------------------------------------------------- FILE *GeoFile; #define maxgeoline 80 Char_t geo_line[maxgeoline]; Char_t det_name[5]; Float_t z_min, z_max, angle,beta; Float_t xl,yl,zl,xl_center,yl_center,zl_center, fval = fField; Char_t *c; Int_t imag; cout << "Opening Magnet file " << FileName << " for " << GetName() << endl; if( !(GeoFile = fopen( FileName,"r"))){ cout << "File not present " << endl; return kFALSE; } TString f(FileName); if (f.Contains(".geo")) { cout << " The magnet info is only in a *.mag file " << endl; return kFALSE; } while(( c = fgets(geo_line,maxgeoline,GeoFile))) { imag = strncmp(geo_line,"MAGNET",6); if( !imag ) { sscanf(geo_line,"MAGNET= %s",det_name); if(!strcmp(det_name, DetectorName)) { beta=0.0; fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," gap x = %f",&xl); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," gap y = %f",&yl); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," gap z = %f",&zl); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," rotation ang = %f",&angle); long nbytes = ftell(GeoFile); fgets(geo_line,maxgeoline,GeoFile); if (sscanf(geo_line," vertical ang = %f",&beta)); else fseek(GeoFile, nbytes, SEEK_SET); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," gap center x = %f",&xl_center); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," gap center y = %f",&yl_center); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," gap center z = %f",&zl_center); fgets(geo_line,maxgeoline,GeoFile); char ftype[20]; sscanf(geo_line," Type=%s",ftype); fFieldType = ftype; // get position in file nbytes = ftell(GeoFile); fgets(geo_line,maxgeoline,GeoFile); if (sscanf(geo_line," Field (KG) = %f",&fval)) fField=fval; else fseek(GeoFile, nbytes, SEEK_SET); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," z min = %f",&z_min); fgets(geo_line,maxgeoline,GeoFile); sscanf(geo_line," z max = %f",&z_max); fEdgeFront = z_min; fEdgeBack = z_max; SetVolumeParameters(xl,yl,zl,angle,beta, xl_center,yl_center,zl_center,"Magnet"); fclose(GeoFile); return kTRUE; } } } Warning("ReadASCIIFile","Did not find %s in %s", DetectorName, FileName); return kFALSE; } //___________________________________________________________________________ void BrMagnetVolume::SetCurrent(const Double_t I , const Char_t* Pol) { // --------------------------------------- // Set field value given the intensity // and polarity of the current // --------------------------------------- if(!strcmp(Pol,"A")) fPolarity=-1.0; else if(!strcmp(Pol,"B")) fPolarity=1.0; else if(!strcmp(Pol,"Off")) //Added by KH 3-Aug-2001 for runs when mag off fPolarity=0.0; else { cerr << "illegal Polarity must by (A/B/Off)" << endl; } fField = fPolarity * (fA+fB*I+fC*I*I)/1000.0; } //___________________________________________________________________________ Double_t BrMagnetVolume::GetCurrent(const Double_t Field ) { // // Get the current corresponding to a Magnetic field // // --------------------------------------- Double_t field = TMath::Abs(fField); Double_t a = fC; Double_t b = fB; Double_t c = fA-field*1000.0; Double_t D = b*b-4*a*c; if(D<0){ Warning("GetCurrent","No solution"); return 0; } Double_t current = (-b+TMath::Sqrt(D))/( 2.0*a); return current; } //______________________________________________________________ ostream& operator<< (ostream & os,BrMagnetVolume *volume_p) { os<<"Volume Name is "<<volume_p->GetName()<<"n"; os<<" Position :" << volume_p->fSystem.GetOrigin() << "n"; os<<" RotMatrix :" << volume_p->GetRotMatrix() << "n"; os<<" Gap :" << volume_p->GetSize()[0]<<","<< volume_p->GetSize()[1]<<","<<volume_p->GetSize()[2]<<")n" <<"Front Effective Edge:" <<volume_p->GetEffectiveEdgeEntrancePlane()<<"n" <<"Back Effective Edge :" <<volume_p->GetEffectiveEdgeExitPlane()<<"n" <<" Field : " << volume_p->GetField() << "n" <<" Bdl : " << volume_p->GetBdl() << endl; os << endl; return os; } //______________________________________________________________ ostream& operator<< (ostream & os,BrMagnetVolume &volume_p) { os<<&volume_p; return os; } //______________________________________________________________ BrPlane3D BrMagnetVolume::GetEffectiveEdgeEntrancePlane() { // ------------------------------------ // return effective edge entrance plane // ------------------------------------ Double_t dl = fEdgeFront; BrPlane3D entranceplane(0,0, dl,0,1, dl,1,0, dl); return entranceplane; } //______________________________________________________________ BrPlane3D BrMagnetVolume::GetEffectiveEdgeExitPlane() { // ------------------------------------ // return effective edge exit plane // ------------------------------------ Double_t dl = fEdgeBack; BrPlane3D exitplane(0,0,dl, 0,1,dl, 1,0,dl); return exitplane; } //______________________________________________________________ BrLine3D BrMagnetVolume::SwimBack(const BrLine3D& line, const Double_t momentum) { // -------------------------------------------------------------- // A routine to take a track (represented by a line) which begins // at the back face of the magnet, use the magnetic field and // momentum and return a line which contains the coordinate where // the track exits the front face of the magnet and the direction // rotated by the change in angle. // -------------------------------------------------------------- Double_t d2l,b2; Double_t cs2, sin1, sin2, th1, th2, theta, cs, si, r; BrVector3D al,aln; BrVector3D xc; //Exit of magnet (where we start to swim back) BrVector3D xe; //Entrance of magnet (where get come out of the front) d2l = fEdgeBack; b2 = fField; BrPlane3D ExitPlane(0,0,d2l,0,1,d2l,1,0,d2l); xc = ExitPlane.GetIntersectionWithLine(line); al = line.GetDirection(); if (TMath::Abs(b2)>0){ // if magnetic field present cs2 = (Float_t)sqrt(al[0]*al[0] + al[2]*al[2]); sin2 = al[0] / cs2; sin1 = GetBdl() / (3335.6 * momentum) + sin2; th1 = (Float_t)TMath::ASin(sin1); th2 = (Float_t)TMath::ASin(sin2); theta = th2 - th1; cs = (Float_t)TMath::Cos(theta); si = (Float_t)TMath::Sin(theta); // Rotate the coordinates for (al[1],al[2]) by the scattering angle aln[0] = al[0] * cs - al[2] * si; aln[2] = al[0] * si + al[2] * cs; aln[1] = al[1]; // These are now direction cosines. // Calculate the position at the entrance of the Magnet r = 2.0 * d2l / (sin1-sin2); Double_t xdiff = r*(Float_t)(TMath::Cos(th2) - TMath::Cos(th1)); Double_t ydiff = TMath::Abs(theta * r / cs2) * al[1]; xe[0] = xc[0] - xdiff; xe[1] = xc[1] - ydiff; xe[2] = -d2l; } else { // no magnetic field, just continue line in same direction d2l = fEdgeFront; BrPlane3D EntrancePlane(0,0, d2l,0,1, d2l, 1,0, d2l); xe = EntrancePlane.GetIntersectionWithLine(line); aln = al; } BrLine3D entrance(xe,aln); return entrance; } //______________________________________________________________ BrLine3D BrMagnetVolume::SwimForward(const BrLine3D& line, const Double_t momentum) { // -------------------------------------------------------------- // A routine to take a track (represented by a line) which begins // at the front face of the magnet, use the magnetic field and // momentum and return a line which contains the coordinate where // the track exits the front face of the magnet and the direction // rotated by the change in angle. // -------------------------------------------------------------- Double_t d2l, b2; Double_t cs2, sin1, sin2, th1, th2, theta, cs, si, r; BrVector3D al, aln; BrVector3D xc; // Exit of magnet (where get come out of the back) BrVector3D xe; // Entrance of magnet (where we start to swim back) BrLine3D entrance; d2l = fEdgeFront; b2 = fField; BrPlane3D EntrancePlane(0,0, d2l, 0,1, d2l,1, 0, d2l); xc = EntrancePlane.GetIntersectionWithLine(line); al = line.GetDirection(); for(Int_t step=0;step<1;step++){ Double_t Bdl; if(step==0) Bdl = GetBdl(); else Bdl = GetBdl(line,entrance); if (TMath::Abs(b2)>0){ // if magnetic field present cs2 = (Float_t)sqrt(al[0]*al[0] + al[2]*al[2]); sin2 = al[0] / cs2; sin1 = - Bdl / (3335.6 * momentum) + sin2; th1 = (Float_t)TMath::ASin(sin1); th2 = (Float_t)TMath::ASin(sin2); theta = th2 - th1; cs = (Float_t)TMath::Cos(theta); si = (Float_t)TMath::Sin(theta); // Rotate the coordinates for (al[1],al[2]) by the scattering angle aln[0] = al[0] * cs - al[2] * si; aln[2] = al[0] * si + al[2] * cs; aln[1] = al[1]; // These are now direction cosines. // Calculate the position at the entrance of the Magnet r = 2.0 * d2l / (sin1-sin2); Double_t xdiff = r*(Float_t)(TMath::Cos(th2) - TMath::Cos(th1)); Double_t ydiff = TMath::Abs(theta * r / cs2) * al[1]; xe[0] = xc[0] - xdiff; xe[1] = xc[1] + ydiff; xe[2] = -d2l; } else { // no magnetic field, just continue line in same direction d2l = fEdgeBack; BrPlane3D ExitPlane(0,0,d2l,0,1,d2l,1,0,d2l); xe = ExitPlane.GetIntersectionWithLine(line); aln = al; } entrance.SetDirection(aln); entrance.SetOrigin(xe); } return entrance; } //______________________________________________________________ Bool_t BrMagnetVolume::GetSwimStatus(const BrLine3D& FrontLine, const BrLine3D& BackLine, Float_t FiduCutX,Float_t FiduCutY) { // -------------------------------------------------------- // This method fits helix to the entry and exit line // and check wheter the helix run within the magnet gap // -------------------------------------------------------- if(Verbose()) cout << FrontLine << "n" << BackLine << "n" << FiduCutX << FiduCutY << endl; Double_t x0,z0,Radius, Radius2; Double_t Xgap = *(GetSize()); Double_t Ygap = *(GetSize()+1); Double_t magLng = fEdgeBack - fEdgeFront; Double_t z1 = fEdgeFront; Double_t z2 = fEdgeBack; BrPlane3D Plane1(0,0,z1, 0,1,z1, 1,0,z1); BrPlane3D Plane2(0,0,z2, 0,1,z2, 1,0,z2); BrVector3D vec1 = Plane1.GetIntersectionWithLine(FrontLine); BrVector3D vec2 = Plane2.GetIntersectionWithLine(BackLine); Double_t x1 = vec1(0); Double_t y1 = vec1(1); Double_t x2 = vec2(0); Double_t y2 = vec2(1); Double_t Xmax = 0; Double_t Ymax = 0; Double_t Xarc, Xent; if (fField != 0){ //if field present Double_t dir1x = FrontLine.GetDirection()[0]; Double_t dir1z = FrontLine.GetDirection()[2]; Double_t size = TMath::Sqrt(dir1x*dir1x + dir1z*dir1z); dir1x /= size; dir1z /= size; Double_t dir2x = BackLine.GetDirection()[0]; Double_t dir2z = BackLine.GetDirection()[2]; size = TMath::Sqrt(dir2x*dir2x+dir2z*dir2z); dir2x /= size; dir2z /= size; // Now define helix (circle in X,Z plane) parameters: Radius2 (r^2), x0 and z0 // // Calculate Radius square, x0, z0 from vector algebra // Note the position of (x0,z0) depends on the bending direction of the // track in the magnet. // Double_t RadiusSquared = ((z2-z1)*(z2-z1)+ (x2-x1)*(x2-x1)) / ((dir2z-dir1z)*(dir2z-dir1z)+(dir2x-dir1x)*(dir2x-dir1x)); Radius = TMath::Sqrt(RadiusSquared); if(dir2x < dir1x) Radius = - Radius; if(Verbose()) cout << x0 << z0 << endl; x0 = x1 + Radius *dir1z; z0 = z1 - Radius *dir1x; if(Verbose()){ cout << Radius << endl; cout << RadiusSquared << endl; cout << x0 << z0 << endl; } // And now we can detemine the maximum helix distance from the // magnet center axis // Xarc is the largest (numerical value) inside the gap of the Helix // The Xend is the positions at the Gap - these must also be checked. // if (TMath::Abs(z0) < magLng/2.){ Xarc = x0 - Radius; Xent = TMath::Max(TMath::Abs(x1),TMath::Abs(x2)); } // If the z0 is outside the effective edge the points to check are // the entrace x1, and x2 values. // else { Xarc = x1; Xent = x2; } } else // fField=0 { Xarc = x1; Xent = x2; } if(Verbose()) cout << "Gap checks " << Xent <<" " << Xarc << endl; Xmax = TMath::Max( TMath::Abs(Xent), TMath::Abs(Xarc)); if (TMath::Abs(y1) <TMath::Abs(y2)) Ymax = y2; else Ymax = y1; // OK, now we can check whether the helix lies within the magnet gap Bool_t TrackTransported = kFALSE; if ((Xmax < (Xgap/2.0 - FiduCutX)) && (TMath::Abs(Ymax) < (Ygap/2.0 - FiduCutY))) TrackTransported=kTRUE; // In case of D1 we have to take into account a Cu shielding box // placed in the front of the magnet: // if(TrackTransported && !strcmp("D1",GetName())){ // These formula also assumes R<0 ie bending to right and (x0,z0) outside // magnet gap- This does not have to be true. Please fix. // Radius = TMath::Abs(Radius); Double_t outerPos = -112.7; //outer addge of the D1 front field clamp? Double_t innerPos = outerPos + 38.1; Double_t InnerX = TMath::Sqrt(Radius2 - (innerPos-z0)*(innerPos-z0)) + x0; Double_t OuterX = TMath::Sqrt(Radius2 - (outerPos-z0)*(outerPos-z0)) + x0; if (InnerX < (-3.56 + FiduCutX) || OuterX < (-1.81 + FiduCutX)) TrackTransported=kFALSE; } return TrackTransported; } //______________________________________________________________ Double_t BrMagnetVolume::GetBdl(const BrLine3D& FrontLine, const BrLine3D& BackLine) { // -------------------------------------------------------- // This method fits helix to the entry and exit line // calculate track lenght in the magnetic field and // returns Bdl const Double_t pi = BrUnits::pi; Double_t z1 = fEdgeFront; Double_t z2 = fEdgeBack; BrPlane3D Plane1(0,0,z1,0,1,z1,1,0,z1); BrPlane3D Plane2(0,0,z2,0,1,z2,1,0,z2); BrVector3D vec1 = Plane1.GetIntersectionWithLine(FrontLine); BrVector3D vec2 = Plane2.GetIntersectionWithLine(BackLine); Double_t x1 = vec1.GetX(); Double_t y1 = vec1.GetY(); Double_t x2 = vec2.GetX(); Double_t y2 = vec2.GetY(); Double_t tang1 = FrontLine.GetDirection()[2]/FrontLine.GetDirection()[0]; Double_t tang2 = BackLine.GetDirection()[2]/BackLine.GetDirection()[0]; // Now define helix (cycle) parameters: Radius2 (r^2), x0 and z0 Double_t z0 = (x2 - x1 - z1*tang1 + z2*tang2) / (tang2 - tang1); Double_t x0 = x2 + (z2 - z0)*tang2; Double_t Radius2 = (x1-x0)*(x1-x0) + (z1-z0)*(z1-z0); Double_t alpha1 = TMath::ATan(tang1); Double_t alpha2 = TMath::ATan(tang2); if(alpha1<0.0) alpha1=alpha1+pi; if(alpha2<0.0) alpha2=alpha2+pi; Double_t dl = (alpha2-alpha1)*TMath::Sqrt(Radius2); return fField*dl; } //_____________________________________________________________________________ void BrMagnetVolume::Update() { //Do an update for a particular run. //For the moment, most of the building is done in geodb manager. //Perhaps, it will be moved soon. For the moment, we simply update //the Keithley values from the DB. const BrRunInfo *run = fRunManager->GetCurrentRun(); Int_t runno = run->GetRunNo(); if(runno == fCurrentRunNo) return; fCurrentRunNo = runno; //Check that we're connected to geometry db if (!fGeometryDb->IsConnected()) { //Try to connect to the geometry database if (!fGeometryDb->Connect()) { Warning("BuildDetectorVolume","couldn't connect to geometry database"); return; } } //Check that we're connected to run db if (!fRunDb->IsConnected()) { // try to connect to the run database if (!fRunDb->Connect()) { Warning("Update", "couldn't connect to run database"); return; } } //Get volume parameters from DB FillVolume(); //part of base class (BrDetectorVolume) //Fill magnet parameters from DB Bool_t stat = FillMagnetParameters(); //Get list of Hall Probe readings for this run. BrDbRun *dbRun = fRunDb->GetRun(runno); //Get start and end time of run Int_t start = dbRun->GetStartTime(); Int_t end = dbRun->GetEndTime(); //Next two lines (FillHallProbeList and UpdateField) //commented out 27-Jun-2002 because of possible problems //with sorting Hall Probe list values //not used for the moment, so comment until we begin to use it. //Should investigate if order by time statement which is not necessary is //perhaps the problem. Also, perhaps we should just take the first value //since is is supposed to be very stable. This may or may not help with //the time spent. //FillHallProbeList(start,end); //Initialize field to start of run. That way the user //at least has that if he doesn't touch this anymore. //UpdateField(start); //Close the DBs so someone else can have our slot. fGeometryDb->Close(); fRunDb->Close(); } //_____________________________________________________________________ Bool_t BrMagnetVolume::FillMagnetParameters() { //Fill the magnet parameters from the DB const BrRunInfo *run = fRunManager->GetCurrentRun(); //Get the magnet parameters from the DB BrDbMagnetVolume *mag = GetMagnetWithCondition(); if(!mag) { Warning("FillMagnetParameters","Parameters for magnet %s do not exist in GeometryDB",GetName()); return 0; } //Put the magnet parameters into the magnet volume SetEdgeFront(mag->GetFrontEdge()); SetEdgeBack(mag->GetBackEdge()); //Now, need to set current. This is a dirty way of doing this, but it //should work for the moment. This coding should probably be implemented //in the BrRunInfo class Int_t icurrent = 0; const Char_t *pol = 0; if(fName.Contains("D1",TString::kIgnoreCase)) { icurrent = run->GetD1Set(); pol = run->GetD1Pol(); } else if(fName.Contains("D2",TString::kIgnoreCase)) { icurrent = run->GetD2Set(); pol = run->GetD2Pol(); } else if(fName.Contains("D3",TString::kIgnoreCase)) { icurrent = run->GetD3Set(); pol = run->GetD3Pol(); } else if(fName.Contains("D4",TString::kIgnoreCase)) { icurrent = run->GetD4Set(); pol = run->GetD4Pol(); } else if(fName.Contains("D5",TString::kIgnoreCase)) { icurrent = run->GetD5Set(); pol = run->GetD5Pol(); } else { Warning("BuildMagnetVolume","Invalid magnet: %d",GetName()); cout<<" Returning 0!!!"<<endl; return 0; } Double_t current = (Double_t)icurrent; SetCurrent(current,pol); } BrDbMagnetVolume *BrMagnetVolume::GetMagnetWithCondition() { //Get detector volumes out of the DB with name like one specified and //valid time less than run time. Then search through and find //the one valid at the latest time which is earlier than the current run. //We do that by looking for the smallest difference between the start of //validity and the run time. const BrRunInfo *run = fRunManager->GetCurrentRun(); Int_t runTime = run->GetUnixStartTime(); Char_t condition[80]; sprintf(condition,"validStart <= %d AND MagnetName like '%s'",runTime,GetName()); TObjArray *arr = fGeometryDb->GetXMagnetVolume(condition); if(!arr) { Warning("GetMagnetVolumeWithCondition","Magnet: No entries found"); return 0; } BrDbMagnetVolume *retVol = 0; Int_t diff; UInt_t big = 1<<31; Int_t minDiff = big - 1; //time difference should not be larger than that!!! Int_t maxRevision = 0; TIter next(arr); BrDbMagnetVolume *volTmp; while((volTmp = (BrDbMagnetVolume*)next())) { diff = runTime - volTmp->GetValidStart(); if(diff < 0) { //Be safe; should never come here because of condition specified above printf("diff < 0!!!; something is wrong; check it outn"); } Int_t revision = volTmp->GetRevisionId(); if(diff < minDiff) { minDiff = diff; retVol = volTmp; maxRevision = revision; } else if(diff == minDiff) { //Case if we have more than one that started at same time. //Pick one with largest revision if(maxRevision < revision) { retVol = volTmp; maxRevision = revision; } } } //Need to create new one copied from old one since old one will be deleted //when we delete arr. if(retVol) retVol = new BrDbMagnetVolume(*retVol); else { Warning("GetMagnetWithCondition","Found no entries for %s that started before run %d",GetName(),run->GetRunNo()); } delete arr; return retVol; } //______________________________________________________________ void BrMagnetVolume::FillHallProbeList(Int_t start, Int_t end) { //Fill the Hall probe list with readings during this run. //Get Hall probe values for magnets during this run //First, delete previous ones. fHallProbeList->SetOwner(kTRUE); fHallProbeList->Delete(); //Get them out of the DB Int_t unit,channel; if(fName.Contains("D1",TString::kIgnoreCase)) { unit = kUnitD1; channel = kChannelD1; } else if(fName.Contains("D2",TString::kIgnoreCase)) { unit = kUnitD2; channel = kChannelD2; } else if(fName.Contains("D3",TString::kIgnoreCase)) { unit = kUnitD3; channel = kChannelD3; } else if(fName.Contains("D4",TString::kIgnoreCase)) { unit = kUnitD4; channel = kChannelD4; } else if(fName.Contains("D5",TString::kIgnoreCase)) { unit = kUnitD5; channel = kChannelD5; } else { Fatal("Update","Invalid magnet %s",GetName()); } fHallProbeList = fRunDb->GetXConditionsKeithley(unit,channel,start,end); } //______________________________________________________________ void BrMagnetVolume::UpdateField(Int_t time) { //This is the routine one would use to update the field based //on the hall probe readings. //Search through the list and take the last value that comes before //time TIter nextHallProbe(fHallProbeList); BrDbConditionsKeithley *hallProbe = 0; if(fHallProbeList->GetEntries() > 0) { hallProbe = (BrDbConditionsKeithley*)fHallProbeList->At(0); if((time + 200) < hallProbe->GetTime()) { Warning("UpdateField","%d is inappropriate time for this run, min is %d",time,hallProbe->GetTime()); return; } } else { Warning("UpdateField","No entries in Hall Probe List!; check it out"); } Int_t count = 0; Float_t value; while((hallProbe = (BrDbConditionsKeithley*)nextHallProbe())) { if(time < hallProbe->GetTime()) { value = hallProbe->GetValue(); SetFieldFromHallProbe(value); return; } count++; } hallProbe = (BrDbConditionsKeithley*)fHallProbeList->Last(); if(time - 200 > hallProbe->GetTime()) { Warning("UpdateField","%d is inappropriate time for this run, max is %d",time,hallProbe->GetTime()); return; } //Set field to last one in list SetFieldFromHallProbe(hallProbe->GetValue()); } void BrMagnetVolume::SetFieldFromHallProbe(Float_t hallProbeValue) { //Set the field given the value of the hall probe reading //printf("New Field to be set to field for Hall Probe value = %f once calibration knownn",hallProbeValue); } //______________________________________________________________ // // $Log: BrMagnetVolume.cxx,v $ // Revision 1.21 2002/08/30 17:35:06 videbaek // Add Verbose getter method in DetectorVolume. // Corrected the checkswim status where the code was wrong for tracks that bends // left, as well as given Nan for straigt incidence tracks. // // Revision 1.20 2002/08/08 15:22:13 ufstasze // Introduced x and y fiducial cut in GetSwimStatus // // Revision 1.19 2002/06/27 22:16:52 hagel // Removed calls to FillHall probe values // // Revision 1.18 2002/06/20 01:30:44 ouerdane // fixed polarity and current setting in FillMagnetParameters // // Revision 1.17 2002/06/06 23:04:22 hagel // Fix small bugs with magnet revisions // // Revision 1.16 2002/04/22 13:14:36 staszel // GetSwimStatus: introduced a copper shielding in the front of D1. // // Revision 1.14 2002/04/16 14:44:12 hagel // Implement Hall Probe reading from Db in ySQL mode. Major surgery on BrGeometryDbManager concerning building BrDetectorVolume and BrMagnetVolume // // Revision 1.13 2002/04/10 13:03:45 ufstasze // Updated parameters for B vs. I for D3 and D4. // New parameters based on Ramiro measurements from March 21 and 27, 2002. // // Revision 1.12 2002/04/10 09:38:06 ouerdane // added rotmatrix in Print // // Revision 1.11 2002/02/24 20:31:58 videbaek // insignificant code cleaning // // Revision 1.10 2002/02/22 21:49:15 videbaek // Add Print method, and give warning for ListParameters as becoming obsolete. // // Revision 1.9 2002/02/08 22:55:48 hagel // Take advantage of new features of BrRotMatrix // // Revision 1.8 2001/12/13 12:39:34 ouerdane // Replaced physical gap length by effective edge gap length in GetSwimStatus // // Revision 1.7 2001/11/05 23:41:42 hagel // Changes to MySQL mode for Geometry DB manager // // Revision 1.6 2001/09/24 14:00:07 staszel // Small correction to GetSwimStatus that allows this method // to deal with zero magnetic fields. // // Revision 1.5 2001/09/22 16:18:18 videbaek // Commit changes to BrDetectorVolume and BrMagnetVolume that // Pawel has made. Check out with test programs as well as reconstruction so declared ok. // // Revision 1.3 2001/08/03 09:19:09 hagel // Small iteration on Geometry DB stuff // // Revision 1.2 2001/07/22 21:32:32 videbaek // Added method GetCurrent // // Revision 1.1.1.1 2001/06/21 14:55:18 hagel // Initial revision of brat2 // // Revision 1.19 2001/06/21 09:40:07 ouerdane // added some checks in the magnet file reading in ReadASCIIFile: // if the returned value of sscanf of the line "Field (kG) = ..." is not zero, // then, read the field value. Otherwise, return to the previous // line and read the rest. This way, fField keeps its default // value set to 9999. The reason is to make a check in the global // tracking classes. If the field has this value, try to retrieve the // right one from the database. If there's no connection to the run // database, then the program stops. // // It means that if you have a dummy value in the mag file, remove it and // put the right one or use the database instead: in this case, remove // the line with "Field (kG) = ..." in the mag file. // // Other change: if the file ends by .geo, ReadASCIIFile returns kFALSE. // The magnet info should only be in a .mag file. // // All of this will soon become obsolete but important for "old-fashioned" // analyses. // // Revision 1.18 2001/05/07 21:17:21 hagel // Changes to implement MySQL Db stuff // // Revision 1.17 2001/03/07 17:36:47 hagel // Changes to use with new MySQL DB access // // Revision 1.16 2001/01/01 20:47:18 bramreco // Add BdL to output in ListParameters // // Revision 1.15 2000/12/27 21:36:47 videbaek // Cosmetic- added checks for non-existing modules added. // // Revision 1.14 2000/12/21 14:37:53 videbaek // Convert current calculated field into kGauss // // Revision 1.13 2000/12/21 14:13:21 videbaek // The sign was not set in SetCurrent ..fix- oops // // Revision 1.12 2000/12/16 01:12:54 videbaek // Set proper types for methods. // // Revision 1.11 2000/12/07 22:12:52 videbaek // Added current setting capabilities // // Revision 1.10 2000/12/06 21:03:50 videbaek // Fix sign error in BrEntrance Plane. // // Revision 1.9 2000/11/22 21:04:48 videbaek // BrMagnetVolume is now derived from BrDetectorVolume. Modified and uniform methods // now. // // Revision 1.8 2000/11/15 20:58:01 videbaek // Added SwimForward to magnet volume. Modified internals. The existing // Get methods are stillvalid. Some Set methods has been added. // // Revision 1.7 2000/10/09 20:48:20 videbaek // Fix a small error in swimback. The entrance point was set at the nominal // magnet gap edge, not the effective edge. // Moved CVS comments to end of code. // // Revision 1.6 2000/06/21 20:42:10 trine // Minor change in BrMagnetVolume::Swimback() - if no magnetic field, just // continue in a straight line through magnet. // // Revision 1.5 2000/05/02 13:34:21 videbaek // removed excessive log comments // // Revision 1.4 1999/04/22 21:35:23 hagel // Improvements in SwimBack() // // Revision 1.3 1999/03/07 00:00:42 hagel // many changes // // Revision 1.2 1998/12/21 20:18:32 videbaek // Added magnet voluems. Additional features for Modules. // New BrMatch intended to replace TSonataMath. Some changes in // matrix routines. // // |
||||||
This page automatically generated by script docBrat by Christian Holm |
Copyright ; 2002 BRAHMS Collaboration
<brahmlib@rcf.rhic.bnl.gov>
|